How to create own dynamic type or dynamic object in C#?
Asked Answered
S

7

204

There is, for example, the ViewBag property of ControllerBase class and we can dynamically get/set values and add any number of additional fields or properties to this object, which is cool. I want to use something like that, beyond MVC application and Controller class in other types of applications. When I tried to create dynamic object and set its property like this:

1. dynamic MyDynamic = new { A="a" };
2. MyDynamic.A = "asd";
3. Console.WriteLine(MyDynamic.A);

I've got RuntimeBinderException with message Property or indexer '<>f__AnonymousType0.A' cannot be assigned to -- it is read only in line 2. Also, I suspect it's not quite what I'm looking for. Maybe is there some class which allows me to do something like:

??? MyDynamic = new ???();
MyDynamic.A = "A";
MyDynamic.B = "B";
MyDynamic.C = DateTime.Now;
MyDynamic.TheAnswerToLifeTheUniverseAndEverything = 42;

with dynamic adding and setting properties.

Simper answered 3/10, 2012 at 13:17 Comment(0)
P
378
dynamic MyDynamic = new System.Dynamic.ExpandoObject();
MyDynamic.A = "A";
MyDynamic.B = "B";
MyDynamic.C = "C";
MyDynamic.Number = 12;
MyDynamic.MyMethod = new Func<int>(() => 
{ 
    return 55; 
});
Console.WriteLine(MyDynamic.MyMethod());

Read more about ExpandoObject class and for more samples: Represents an object whose members can be dynamically added and removed at run time.

Pint answered 3/10, 2012 at 13:21 Comment(1)
Please vote for this feature in Visual Studio UserVoice.Probably
R
55
dynamic myDynamic = new { PropertyOne = true, PropertyTwo = false};
Receptacle answered 17/10, 2019 at 15:19 Comment(0)
S
53

I recently had a need to take this one step further, which was to make the property additions in the dynamic object, dynamic themselves, based on user defined entries. The examples here, and from Microsoft's ExpandoObject documentation, do not specifically address adding properties dynamically, but, can be surmised from how you enumerate and delete properties. Anyhow, I thought this might be helpful to someone. Here is an extremely simplified version of how to add truly dynamic properties to an ExpandoObject (ignoring keyword and other handling):

// my pretend dataset
List<string> fields = new List<string>();
// my 'columns'
fields.Add("this_thing");
fields.Add("that_thing");
fields.Add("the_other");

dynamic exo = new System.Dynamic.ExpandoObject();

foreach (string field in fields)
{
    ((IDictionary<String, Object>)exo).Add(field, field + "_data");
}

// output - from Json.Net NuGet package
textBox1.Text = Newtonsoft.Json.JsonConvert.SerializeObject(exo);
Sanderson answered 29/8, 2016 at 14:58 Comment(2)
Anyone know why we have to type cast to access the Add method? That seems strange to me.Ethbun
This is because the ExpandoObject does not expose a direct Add method. If you try and use .Add, it treats that statement as if you are wanting to add an 'Add' member to the object. You have to expose the underlying data structure, basically getting to the Dictionary interface, to access its Add method. This is also the case for removing a member or anything else that is offered in a Dictionary but not exposed in the ExpandoObject itself. Newer documentation seem to explain this requirement better: docs.microsoft.com/en-us/dotnet/api/…Sanderson
F
36

ExpandoObject is what are you looking for.

dynamic MyDynamic = new ExpandoObject(); // note, the type MUST be dynamic to use dynamic invoking.
MyDynamic.A = "A";
MyDynamic.B = "B";
MyDynamic.C = "C";
MyDynamic.TheAnswerToLifeTheUniverseAndEverything = 42;
Foremast answered 3/10, 2012 at 13:21 Comment(0)
S
31
var data = new { studentId = 1, StudentName = "abc" };  

Or value is present

var data = new { studentId, StudentName };
Snappish answered 19/11, 2019 at 12:42 Comment(2)
Thank you, exactly what I was looking forSyncope
This is not a dynamic object but an anonymous type.Kristopher
A
16

You can use ExpandoObject Class which is in System.Dynamic namespace.

dynamic MyDynamic = new ExpandoObject();
MyDynamic.A = "A";
MyDynamic.B = "B";
MyDynamic.C = "C";
MyDynamic.SomeProperty = SomeValue
MyDynamic.number = 10;
MyDynamic.Increment = (Action)(() => { MyDynamic.number++; });

More Info can be found at ExpandoObject MSDN

Amyl answered 3/10, 2012 at 13:55 Comment(0)
A
7
dynamic MyDynamic = new ExpandoObject();
Antisocial answered 3/10, 2012 at 13:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.