8 Replies - 787 Views - Last Post: 13 September 2016 - 12:05 PM Rate Topic: -----

#1 ScottinTexas   User is offline

  • D.I.C Regular

Reputation: 12
  • View blog
  • Posts: 312
  • Joined: 13-March 12

Identify the object type of UserState

Posted 13 September 2016 - 05:28 AM

My background worker reports progress in a couple of places and I use the user state to return an object. In one case the user state is an observable collection of ports, in another it is a class called DataFile. I am not getting the syntax right to determine the types in a switch statement.
        private void WorkerReporting(object sender, ProgressChangedEventArgs e)
        {

            switch ((String)e.UserState.GetType().ToString())
            {
                case "DataFile":
                    {
                        HandleCompletedTestFile((DataFile)e.UserState);
                        break;
                    }

                case "ObservableCollection":
                    {
                        Ports=(ObservableCollection<Comport>)e.UserState;
                        break;
                    }
            };
        }



I guess I'm not getting it right since the switch statement is completely bypassed. According to MSDN the method GetType returns "...the Type of the current instance.(Inherited from Object.)." That''s not very clear to me. Is it the current instance of the BackgroundWorker? If so, isn't the type BackgroundWorker? I took it to mean the instance of the object passed back to the ProgressChanged event in UserState.

Thanks for the help.

Is This A Good Question/Topic? 0
  • +

Replies To: Identify the object type of UserState

#2 andrewsw   User is offline

  • never lube your breaks
  • member icon

Reputation: 6819
  • View blog
  • Posts: 28,255
  • Joined: 12-December 12

Re: Identify the object type of UserState

Posted 13 September 2016 - 05:36 AM

Why don't you print out the string?
Was This Post Helpful? 0
  • +
  • -

#3 ScottinTexas   User is offline

  • D.I.C Regular

Reputation: 12
  • View blog
  • Posts: 312
  • Joined: 13-March 12

Re: Identify the object type of UserState

Posted 13 September 2016 - 06:17 AM

Here's what I get in the debugger quickwatch/Text Viewer.

Quote

System.Collections.ObjectModel.ObservableCollection`1[System.IO.Ports.SerialPort]


Now what? This is what it looks like in the debugger

Quote

System.Collections.ObjectModel.ObservableCollection<System.IO.Ports.SerialPort>.SimpleMonitor |
{System.Collections.ObjectModel.ObservableCollection<System.IO.Ports.SerialPort>.SimpleMonitor}


I don't know what to do with this. Should my case statement be "System.Collections.ObjectModel.ObservableCollection<System.IO.Ports.SerialPort>.SimpleMonitor" or does the fact that I have using statements, "System.Collections.ObjectModel;" and "System.IO.Ports;" mean that I don't have to spell out the entire namespace? And what is this Simple Monitor business?

From the looks of the above quickwatch it didn't do ToString() very well. Without the ToString() method I get ObservableCollection'1. I don't know what the apostrophe 1 is.

OK, so if I gave you enough, how would you write the case statement? Or the switch statement, for that matter.

I appreciate your response.

PS: Digging into the quick watch deeper I discovered that I am throwing an exception; "-DeclaringMethod 'e.UserState.GetType().DeclaringMethod' threw an exception of type 'System.InvalidOperationException' System.Reflection.MethodBase {System.InvalidOperationException} AND

+GenericParameterPosition 'e.UserState.GetType().GenericParameterPosition' threw an exception of type 'System.InvalidOperationException' int {System.InvalidOperationException}

PPS:
I should add the Listener class.

        public void OpenPorts()
        {

            _ports = new ObservableCollection<SerialPort>();
            foreach (string nm in SerialPort.GetPortNames())
            {

                SerialPort sp = new SerialPort();
                sp.PortName = nm;
                sp.ReadBufferSize = 2048;
                sp.DiscardNull = true;
                sp.RtsEnable = true;
                sp.DtrEnable = true;

                sp.DataReceived += DataReceived;
                _ports.Add(sp);
                try
                {
                    sp.Open();
                }
                catch (Exception e)
                {

                    MessageBox.Show(e.Message + '\n' + e.Data);
                }
            }
            try
            {
               Worker.ReportProgress(100, _ports);
            }
            catch(Exception a)
            {
                MessageBox.Show("You screwed up. " + a.Message + '\n' + a.InnerException);
            }
            _portsOpen = true;
        }


This post has been edited by ScottinTexas: 13 September 2016 - 06:26 AM

Was This Post Helpful? 0
  • +
  • -

#4 Skydiver   User is online

  • Code herder
  • member icon

Reputation: 7107
  • View blog
  • Posts: 24,134
  • Joined: 05-May 12

Re: Identify the object type of UserState

Posted 13 September 2016 - 06:18 AM

Also, why not simply use the is and as C# keywords? Why take on the overhead of having to convert the type to a string and take on the risk of having typo's in your comparison strings?

Anyway, the type strings returned are fully qualified type names, they include the full namespace, not just the type name within the namespace.
Was This Post Helpful? 0
  • +
  • -

#5 ScottinTexas   User is offline

  • D.I.C Regular

Reputation: 12
  • View blog
  • Posts: 312
  • Joined: 13-March 12

Re: Identify the object type of UserState

Posted 13 September 2016 - 07:02 AM

Thanks Skydiver,

I don't know the is and as key words. Have to check that out. So how would you use a switch to see what was being returned in the ProgressChanged?
Was This Post Helpful? 0
  • +
  • -

#6 Skydiver   User is online

  • Code herder
  • member icon

Reputation: 7107
  • View blog
  • Posts: 24,134
  • Joined: 05-May 12

Re: Identify the object type of UserState

Posted 13 September 2016 - 07:21 AM

Instead of using a switch, just have a chain of if-else if.

But if you really want to use switch, I believe this will actually work:
switch (obj.GetType())
{
case typeof(Foo):
    break;

case typeof(Bar):
    break;
}



In general, though if you are making a decision based on types, it's a code smell that indicates that you should likely be using the Strategy pattern.

This post has been edited by Skydiver: 13 September 2016 - 07:31 AM
Reason for edit:: Edit after: Looks like that only worked in an early prototype of C# I had played with. Current versions won't let you switch on the type object.

Was This Post Helpful? 0
  • +
  • -

#7 Skydiver   User is online

  • Code herder
  • member icon

Reputation: 7107
  • View blog
  • Posts: 24,134
  • Joined: 05-May 12

Re: Identify the object type of UserState

Posted 13 September 2016 - 07:37 AM

As as alternative to the switch you can use a Dictionary<Type, Action>():
var basedOnType = new Dictionary<Type, Action>()
{
    [typeof(Foo)] = () => Console.WriteLine("I have Foo!"),
    [typeof(Bar)] = () => { int x = 2; },
};

var obj = new Bar();
basedOnType[obj.GetType()]();            


Was This Post Helpful? 0
  • +
  • -

#8 ScottinTexas   User is offline

  • D.I.C Regular

Reputation: 12
  • View blog
  • Posts: 312
  • Joined: 13-March 12

Re: Identify the object type of UserState

Posted 13 September 2016 - 10:51 AM

Thank you. First off, I changed to "as" instead of casting syntax. If nothing else it is cleaner reading to me. Secondly to make my switch statement work I switched on "e.UserState.GetType().Name" which worked just fine, for the moment. I say 'for the moment' because often I say 'It worked great' only to find it wont work for a second or third thing, whatever that may be.

I'll give the Dictionary<Type, Action> method a try. I just can never seem to get the syntax of a Lambda statement correct. But I'll read that again and see what I come up with.

Thanks, again. I appreciate your help.
Was This Post Helpful? 0
  • +
  • -

#9 Curtis Rutland   User is offline

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 5106
  • View blog
  • Posts: 9,283
  • Joined: 08-June 10

Re: Identify the object type of UserState

Posted 13 September 2016 - 12:05 PM

Lambda syntax is easy if you break it down:

//full lambda syntax
(type param1, type param var2, ... type paramN) => { /* code goes here, optional return: */ return someValue; }



Compare that to a function definition (a lambda is an "anonymous function"), which also takes parameters and optionally returns a value.

Now, that's the "full" version. Much of a lambda can be inferred by the compiler (Such as the types of the parameters ) as well as some shortcuts.

Couple of rules for the "shortcuts":

If there is only one parameter, you can omit the parenthesis on the parameter list, and you can almost always omit the types of variables, since the compiler can infer that:

i => { return i + 1; }


If the lambda is a one-liner, you can even omit the brackets and the return statement, as the result of the expression will be returned:

i => i + 1;


To put this into perspective, these "fit" in the Action and Func delegates. Action for "void" delegates (functions that don't return a value) and Func for those that do.

For instance, that last lambda I showed would be a Func<int, int> (because it takes an int, and returns an int).

Func<int, int> addOne = i => i + 1;

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1