How to create a List with a dynamic object type

136,726

Solution 1

Just use dynamic as the argument:

var list = new List<dynamic>();

Solution 2

It appears you might be a bit confused as to how the .Add method works. I will refer directly to your code in my explanation.

Basically in C#, the .Add method of a List of objects does not COPY new added objects into the list, it merely copies a reference to the object (it's address) into the List. So the reason every value in the list is pointing to the same value is because you've only created 1 new DyObj. So your list essentially looks like this.

DyObjectsList[0] = &DyObj; // pointing to DyObj
DyObjectsList[1] = &DyObj; // pointing to the same DyObj
DyObjectsList[2] = &DyObj; // pointing to the same DyObj

...

The easiest way to fix your code is to create a new DyObj for every .Add. Putting the new inside of the block with the .Add would accomplish this goal in this particular instance.

var DyObjectsList = new List<dynamic>; 
if (condition1) { 
    dynamic DyObj = new ExpandoObject(); 
    DyObj.Required = true; 
    DyObj.Message = "Message 1"; 
    DyObjectsList .Add(DyObj); 
} 
if (condition2) { 
    dynamic DyObj = new ExpandoObject(); 
    DyObj.Required = false; 
    DyObj.Message = "Message 2"; 
    DyObjectsList .Add(DyObj); 
} 

your resulting List essentially looks like this

DyObjectsList[0] = &DyObj0; // pointing to a DyObj
DyObjectsList[1] = &DyObj1; // pointing to a different DyObj
DyObjectsList[2] = &DyObj2; // pointing to another DyObj

Now in some other languages this approach wouldn't work, because as you leave the block, the objects declared in the scope of the block could go out of scope and be destroyed. Thus you would be left with a collection of pointers, pointing to garbage.

However in C#, if a reference to the new DyObjs exists when you leave the block (and they do exist in your List because of the .Add operation) then C# does not release the memory associated with that pointer. Therefore the Objects you created in that block persist and your List contains pointers to valid objects and your code works.

Share:
136,726
BumbleBee
Author by

BumbleBee

Updated on June 07, 2020

Comments

  • BumbleBee
    BumbleBee almost 4 years

    How can I create a new List<T> where the T is a dynamic Type object.

    I have

    dynamic DyObj = new ExpandoObject();
    
    if (condition1)
    {
      DyObj.Required = true;
      DyObj.Message = "This is the first property being accessed through dynamic object";
    }
    if (condition2)
    {
        DyObj.Required = false;
        DyObj.Message = "This is the second property....";
    }
    // and so on...
    

    I want to create List<Dyobj> and assign all the messages to Dyobj based on conditions.

    Follow up data from comments:

    var DyObjectsList = new List<dynamic>; 
    dynamic DyObj = new ExpandoObject(); 
    if (condition1) { 
        DyObj.Required = true; 
        DyObj.Message = "Message 1"; 
        DyObjectsList.Add(DyObj); 
    } 
    if (condition2) { 
        DyObj.Required = false; 
        DyObj.Message = "Message 2"; 
        DyObjectsList.Add(DyObj); 
    } 
    

    interestingly all the objects in DyObjectsList are replaced with the values of the last assigned object.

  • BumbleBee
    BumbleBee almost 13 years
    @Krik thank you. here is what i did. var DyObjectsList = new List<dynamic>; dynamic DyObj = new ExpandoObject(); if (condition1) { DyObj.Required = true; DyObj.Message = "Message 1"; DyObjectsList .Add(DyObj); } if (condition2) { DyObj.Required = false; DyObj.Message = "Message 2"; DyObjectsList .Add(DyObj); } interestingly all the objects in DyObjectsList are replaced with the values of the last assigned object.
  • Kirk Woll
    Kirk Woll almost 13 years
    @BumbleBee, this is because you are overwriting the values of your object. You instantiate one instance of your DyObj and the proceed to assign values to that same instance twice. You should move the line dynamic DyObj = new ExpandoObject(); inside your if blocks, and you should end up with two copies of that line since you want to add two separate instances.