1

Why do I get this error? Here is the code:

MyClass item = new MyClass{ id=1 };
List<object> items = new List<object>();
items.Add(item);

object getitem = items[0];
int itemid = getitem.id; // <-error

In debugger the getitem object shows as having the id property, but I can't extract it without getting this error. How do I extract the id property from this object?

Control Freak
  • 12,965
  • 30
  • 94
  • 145
  • 4
    `object` has no `id` property. – Preston Guillot Aug 25 '14 at 02:08
  • `object getitem` does though – Control Freak Aug 25 '14 at 02:08
  • 2
    You need to cast it, int itemid = ((MyClass)getitem).id; – RenniePet Aug 25 '14 at 02:08
  • Here is link about casting: http://msdn.microsoft.com/en-us/library/ms173105.aspx – Snorex Aug 25 '14 at 02:09
  • 6
    Do you want a `List` instead of a `List`? – Blorgbeard Aug 25 '14 at 02:12
  • @Blorgbeard I changed it to `List` and `object` to `MyClass` and it all seemed to work--This is probably the most appropriate way to do it (without casting, etc.). You have the best answer since this is what I did. – Control Freak Aug 25 '14 at 02:21
  • ZeeTee, that's great! I won't bother posting an answer, since @Kyle's answer appears to cover it. – Blorgbeard Aug 25 '14 at 02:26
  • I see that your previous experience is mostly with JavaScript. So maybe the guy who answered that you should consider "dynamic" was maybe on the right track. It depends on which kind of C# programs you are intending to get into. http://stackoverflow.com/questions/2690623/what-is-the-dynamic-type-in-c-sharp-4-0-used-for (I don't understand why his answer got down-voted without comment, and I regret that he then deleted it.) – RenniePet Aug 25 '14 at 03:00

2 Answers2

7

The compiler doesn't know that the actual object contained in getitem is of type MyClass, because you've told it to expect an object, which could be just about anything. Imagine you'd done this instead:

List<object> items = new List<object>();
items.Add( "Hello, World!" );

object getitem = items[0];
int itemid = getitem.id; // <-error

A string is also an object, so it's perfectly reasonable to put it in a List<object>. In fact, anything can be put into an object, so the compiler can only guarantee that whatever is in there can do what an object can do (which is have methods GetHashCode, Equals, and ToString).

Consider making your list more specific:

MyClass item = new MyClass{ id=1 };
List<MyClass> items = new List<MyClass>();
items.Add( item );

MyClass getitem = items[0];
int itemid = getitem.id;

If that's not an acceptable solution, then you'll need to cast the result from the list so the compiler knows it's actually dealing with an instance of MyClass:

MyClass getitem = (MyClass) items[0];
int itemid = getitem.id;
Kyle
  • 6,500
  • 2
  • 31
  • 41
  • 1
    Good explanation, but your example in the middle is confusing, "Hello World" isn't an integer. – RenniePet Aug 25 '14 at 02:22
  • @RenniePet I'm not sure why that matters. The only thing I need to do is add any object that doesn't have an `id` member to illustrate why it won't work. The idea is to show that if you expect to get an instance of `MyClass` out of the list then it should probably be typed that way to begin with. – Kyle Aug 25 '14 at 02:24
  • 1
    @Kyle, your example doesn't compile - you can't add a string to a `List` -- we're talking about the second code block, not the first. – Blorgbeard Aug 25 '14 at 02:25
  • @Blorgbeard, d'oh, copied and pasted, I see what RenniePet was referring to now. – Kyle Aug 25 '14 at 02:26
4

The debugger is smart enough to know what type getitem really is and will display the properties. If you change it to:

MyClass getitem = (MyClass) items[0];

it will work for you. What your doing is casting the object instance to a MyClass type so the compiler knows it has an id property.

Steve
  • 502
  • 3
  • 12