PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197

PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
List Object question-VBForums
Results 1 to 10 of 10

Thread: List Object question

  1. #1

    Thread Starter
    Member
    Join Date
    Mar 2015
    Posts
    45

    List Object question

    I'm using the BackgroundWorker object to run a report in the background. I need to pass in a parameter to the BackgroundWorker DoWork function.

    I found some code to do it:

    Code:
    List<object> arguments = new List<object>();
    arguments.Add(argument 1);
    arguments.Add(argument 1);
    arguments.Add(argument n);
    
    backgroundWorker.RunWorkerAsync(arguments); 
    
    private void worker_DoWork(object sender, DoWorkEventArgs e) 
    {
        List<object> genericlist = e.Argument as List<object>;
    }
    I can refer to the arguments in the _DoWork like this:

    genericlist[0]

    But I can't refer them directly from the "e" parameter like this:

    e.Argument[0]

    Why is that?

  2. #2
    Fanatic Member PlausiblyDamp's Avatar
    Join Date
    Dec 2016
    Location
    Newport, UK
    Posts
    1,023

    Re: List Object question

    When you try to refer to them directly do you get an error? If so what does the error message say?

  3. #3
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    102,166

    Re: List Object question

    That's because the e.Argument property is declared as type Object, because it has to be able to refer to any type of object. The Object class has no idexer so you can't index a property of type Object.

    In the code you posted, you are performing a cast to type List<object>. That type does have an indexer so the resulting reference can be indexed. The whole point of a cast is to expose members of an object that are not possessed by the type of reference used to access it. It doesn't matter what type of object you have if you're referring to it via a reference of type Object. In that case, you can only access members of type Object.

    I like to think of it this way. Let's say that you have a pet iguana that is sick. You put it in a box and take it to the vet. When you walk in, all the vet knows is that you have an animal, but not what type of animal it is. At that stage, the vet cannot consider any sort of treatment that would not be appropriate for any and every animal. Once you take your iguana out of the box, the vet knows exactly what it is and can now consider treatments specific to iguanas. In programming terms, you started with a variable of type Animal and so only members of the Animal class were accessible. You then cast that variable as type Iguana, so members of the Iguana class then became accessible too.

  4. #4

    Thread Starter
    Member
    Join Date
    Mar 2015
    Posts
    45

    Re: List Object question

    Quote Originally Posted by jmcilhinney View Post
    That's because the e.Argument property is declared as type Object, because it has to be able to refer to any type of object. The Object class has no idexer so you can't index a property of type Object.

    In the code you posted, you are performing a cast to type List<object>. That type does have an indexer so the resulting reference can be indexed. The whole point of a cast is to expose members of an object that are not possessed by the type of reference used to access it. It doesn't matter what type of object you have if you're referring to it via a reference of type Object. In that case, you can only access members of type Object.

    I like to think of it this way. Let's say that you have a pet iguana that is sick. You put it in a box and take it to the vet. When you walk in, all the vet knows is that you have an animal, but not what type of animal it is. At that stage, the vet cannot consider any sort of treatment that would not be appropriate for any and every animal. Once you take your iguana out of the box, the vet knows exactly what it is and can now consider treatments specific to iguanas. In programming terms, you started with a variable of type Animal and so only members of the Animal class were accessible. You then cast that variable as type Iguana, so members of the Iguana class then became accessible too.
    Does that work like that in all cases? I don't have VS here so I can't test it.

    For example:

    Code:
    SomeObject s1 = new SomeObject();
    SomeObject s2 = new SomeObject();
    Object o = new Object();
    
    o = s1; 'at this point you can't reference o
    
    s2 = o; 'now you can reference it
    And then I'm wondering if you could just use "var" instead of "object".

  5. #5
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    102,166

    Re: List Object question

    There are a number of issues there. Firstly, what's the point of this:
    Code:
    Object o = new Object();
    when on the very next line you do this:
    Code:
    o = s1; 'at this point you can't reference
    and the object you created on the previous line is replaced and discarded without ever being used?

    Secondly, this:
    Code:
    o = s1; 'at this point you can't reference
    There's nothing stop you referencing the object assigned to the o variable. What you can't do is access members of that object that are not members of the type of the o variable. o is type Object so you can only access members of that type, e.g. ToString. Any member declared in the SomeObject type are inaccessible via the o variable.

    Thirdly, this line will not compile:
    Code:
    s2 = o; 'now you can reference it
    You can't assign an Object reference to a SomeObject variable because there's no guarantee that the object referred to is of that type. To assign a reference to a variable of a more specific type, you need to cast:
    Code:
    s2 = (SomeObject) o; 'now you can reference it
    You can also use the as operator to cast but you should only do so in circumstances where you reasonably know the type of the object for sure. You could do this:

    Code:
    s2 = o as SomeObject; 'now you can reference it
    but it would be inappropriate in this context. The point of the as operator is that the result will be null if the cast is not valid, whereas an explicit cast will throw an exception. As an example of where you might reasonably use the as operator, consider that you might want to do something with only TextBox controls on a form:
    csharp Code:
    1. foreach (var ctl in Controls)
    2. {
    3.     var tb = ctl as TextBox;
    4.  
    5.     if (tb != null)
    6.     {
    7.         // Use tb here.
    8.     }
    9. }
    Any use of the as operator should be followed by a null check. If it's not, you shouldn't be using as.

    Finally and least importantly, you're using VB comments in that C# code. C# comments are denoted with a two slashes rather than a single-quote.

  6. #6

    Thread Starter
    Member
    Join Date
    Mar 2015
    Posts
    45

    Re: List Object question

    Quote Originally Posted by jmcilhinney View Post
    There are a number of issues there. Firstly, what's the point of this:
    Code:
    Object o = new Object();
    when on the very next line you do this:
    Code:
    o = s1; 'at this point you can't reference
    and the object you created on the previous line is replaced and discarded without ever being used?

    Secondly, this:
    Code:
    o = s1; 'at this point you can't reference
    There's nothing stop you referencing the object assigned to the o variable. What you can't do is access members of that object that are not members of the type of the o variable. o is type Object so you can only access members of that type, e.g. ToString. Any member declared in the SomeObject type are inaccessible via the o variable.

    Thirdly, this line will not compile:
    Code:
    s2 = o; 'now you can reference it
    You can't assign an Object reference to a SomeObject variable because there's no guarantee that the object referred to is of that type. To assign a reference to a variable of a more specific type, you need to cast:
    Code:
    s2 = (SomeObject) o; 'now you can reference it
    You can also use the as operator to cast but you should only do so in circumstances where you reasonably know the type of the object for sure. You could do this:

    Code:
    s2 = o as SomeObject; 'now you can reference it
    but it would be inappropriate in this context. The point of the as operator is that the result will be null if the cast is not valid, whereas an explicit cast will throw an exception. As an example of where you might reasonably use the as operator, consider that you might want to do something with only TextBox controls on a form:
    csharp Code:
    1. foreach (var ctl in Controls)
    2. {
    3.     var tb = ctl as TextBox;
    4.  
    5.     if (tb != null)
    6.     {
    7.         // Use tb here.
    8.     }
    9. }
    Any use of the as operator should be followed by a null check. If it's not, you shouldn't be using as.

    Finally and least importantly, you're using VB comments in that C# code. C# comments are denoted with a two slashes rather than a single-quote.
    I figured the syntax wasn't right, I was just trying to understand a general concept. I'm trying to understand if this is the preferred way to pass an object into a function? To pass the specific object and then receive it as a generic object and then assign it back to the specific object?

    Like in this example I used previously:

    Code:
    List<object> arguments = new List<object>();
    arguments.Add(argument 1);
    arguments.Add(argument 1);
    arguments.Add(argument n);
    
    backgroundWorker.RunWorkerAsync(arguments); 
    
    private void worker_DoWork(object sender, DoWorkEventArgs e) 
    {
        List<object> genericlist = e.Argument as List<object>;
    }

    One question I have is where does the "casting" occur in the above example?

    Why don't you have to cast arguments to type Object before you pass it to the DoWork function?

    Code:
    List<object> arguments = new List<object>();
    arguments.Add(argument 1);
    arguments.Add(argument 1);
    arguments.Add(argument n);
    backgroundWorker.RunWorkerAsync((Object)arguments); 
    
    private void worker_DoWork(object sender, DoWorkEventArgs e)
    Yeah, I'm switching over from VB as you can tell.

    Thanks!

  7. #7
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    40,887

    Re: List Object question

    Quote Originally Posted by madison320 View Post
    One question I have is where does the "casting" occur in the above example?
    It is this end of this line:
    Code:
        List<object> genericlist = e.Argument as List<object>;
    Why don't you have to cast arguments to type Object before you pass it to the DoWork function?
    Data types are classes, and classes can be based on others (and add more functionality on top).

    The Object data type is the most basic data type, and all others are based on Object (and often something else in between, so TextBox is based on Control which is based on Object), so everything supports the basic functionality that Object provides... and that means you can place anything into a variable/parameter with the data type Object without needing any conversion or casting - it's only going back the other way you need to worry, because any added functionality wont be available otherwise.

  8. #8

    Thread Starter
    Member
    Join Date
    Mar 2015
    Posts
    45

    Re: List Object question

    Quote Originally Posted by si_the_geek View Post
    It is this end of this line:
    Code:
        List<object> genericlist = e.Argument as List<object>;
    Data types are classes, and classes can be based on others (and add more functionality on top).

    The Object data type is the most basic data type, and all others are based on Object (and often something else in between, so TextBox is based on Control which is based on Object), so everything supports the basic functionality that Object provides... and that means you can place anything into a variable/parameter with the data type Object without needing any conversion or casting - it's only going back the other way you need to worry, because any added functionality wont be available otherwise.
    I meant before that. During the passing of the List object to RunWorkerAsync. Passing a parameter is the same as an assignment statement,correct?

    Code:
    backgroundWorker.RunWorkerAsync(arguments); 
    
    private void worker_DoWork(object sender, DoWorkEventArgs e)
    When you pass "arguments" to "e" (via the Event Handler), isn't that an assignment statement like this:

    Code:
    e = arguments;

    Don't they need to be the same type?

    Shouldn't it be like this since "e" is of type "Object" and arguments is of type "List"?

    Code:
    e = arguments as Object;

  9. #9
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    102,166

    Re: List Object question

    You only have to cast if you're going from less specific to more specific. If you're going from less specific to more specific then the compiler already knows that the object is that type. For instance, when calling RunWorkerAsync, the parameter is type [I]Object/I], so you can pass a reference of type Object or any type that inherits it. Given that every type in the Framework inherits Object, every object IS an instance of the Object type.

    Go back to my vet example. When the vet only knows that you have an animal, they cannot prescribe treatments that aren't appropriate for every type of animal. Once they know that you have an iguana, they can then prescribe treatments that are specific to iguanas, but does that mean that they are prevented from prescribing treatments that are appropriate for all animals? Of course not. An iguana doesn't stop being an animal because it's an iguana. Similarly, a List<object> doesn't stop being an Object so you can use it anywhere an Object reference is expected without a cast.

  10. #10

    Thread Starter
    Member
    Join Date
    Mar 2015
    Posts
    45

    Re: List Object question

    Quote Originally Posted by jmcilhinney View Post
    You only have to cast if you're going from less specific to more specific. If you're going from less specific to more specific then the compiler already knows that the object is that type. For instance, when calling RunWorkerAsync, the parameter is type [I]Object/I], so you can pass a reference of type Object or any type that inherits it. Given that every type in the Framework inherits Object, every object IS an instance of the Object type.

    Go back to my vet example. When the vet only knows that you have an animal, they cannot prescribe treatments that aren't appropriate for every type of animal. Once they know that you have an iguana, they can then prescribe treatments that are specific to iguanas, but does that mean that they are prevented from prescribing treatments that are appropriate for all animals? Of course not. An iguana doesn't stop being an animal because it's an iguana. Similarly, a List<object> doesn't stop being an Object so you can use it anywhere an Object reference is expected without a cast.
    That makes sense.

    Thanks!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width