Why iteration of a list with anonymous object works with array but does not work with ListObject?

8

I tried the following iteration with C #:

    var objects = List<Object>{
        new {Id = 2, Nome = "Wallace"},
        new {Id = 4, Nome = "Cigano"}
    };

    foreach (var user in objects) {
        Console.WriteLine ("Meu id é {0}", user.Id);
        Console.WriteLine ("Meu nome é {0}", user.Nome);
    }

See the error in DotNetFiddle

You gave the following error:

  

Type object does not contain a definition for Id and not method Id extension could be found.

But when I do it works:

var objects = new []{
    new {Id = 2, Nome = "Wallace"},
    new {Id = 4, Nome = "Cigano"}
};

If new {} is Object I thought I had no problem using List<Object> , but I can only do this with Array.

    
asked by anonymous 14.06.2016 / 20:45

1 answer

7

You are creating a list of Object . Look at the documentation for this class . See if there is Id and Nome members in the documentation. There is not. Will it magically appear? It's not, it's using a statically typed language. So the compiler tells you that there is not this that you want to use. You can play any object, including the built-in classes created to use the anonymous types in>>, but at the time of accessing the members of an object qualified as object you can only access the ones that are available in the type. It's interface segregation.

In theory it would have a solution. It makes a cast pro real type you are putting into the list and there you will gain access to members of this type. The problem is that you used an anonymous type (which is an inner class that the compiler generates and gives a name that only it knows), and to do a cast you need to say the name of the type you want promote. How do you, programmer, do this? There is no way.

So the real solution is to create a collection that does not have to specify the type of object it will contain. For C # fault (maybe justifiable, I can not say, but I can see some sense) only the array can do this. So the solution is to use it.

If you really need the list, then you can convert the array to list that will work, because the compiler will handle all that is needed and cast, if is necessary, it will be inserted by it with the name that it generated itself.

The var was created just for this. If you have the variable type printed, it looks like this:

<>f__AnonymousType0'2[System.Int32,System.String][]

See showing in DotNetFiddle and in CodingGround .

Or convert to list:

System.Collections.Generic.List'1[<>f__AnonymousType0'2[System.Int32,System.String]]

There was even a chat discussion about using dynamic to resolve this. In fact, dynamic shuts off the compiler check, and you can use the concrete members of any existing object over C # type security. The same goes for access with the use of reflection that gives you access to everything you want without the compiler having control. This is philosophically wrong, it is wanting to make C # turn PHP (roughly), does not bring any benefit and mostly changes the semantics of what is asked in the question.

    
14.06.2016 / 21:11