How to Create Dynamic Properties in C#

Dynamically Add C# Properties at Runtime

Have you taken a look at ExpandoObject?

see: https://docs.microsoft.com/en-us/dotnet/api/system.dynamic.expandoobject

From MSDN:

The ExpandoObject class enables you to add and delete members of its instances at run time and also to set and get values of these members. This class supports dynamic binding, which enables you to use standard syntax like sampleObject.sampleMember instead of more complex syntax like sampleObject.GetAttribute("sampleMember").

Allowing you to do cool things like:

dynamic dynObject = new ExpandoObject();
dynObject.SomeDynamicProperty = "Hello!";
dynObject.SomeDynamicAction = (msg) =>
{
Console.WriteLine(msg);
};

dynObject.SomeDynamicAction(dynObject.SomeDynamicProperty);

Based on your actual code you may be more interested in:

public static dynamic GetDynamicObject(Dictionary<string, object> properties)
{
return new MyDynObject(properties);
}

public sealed class MyDynObject : DynamicObject
{
private readonly Dictionary<string, object> _properties;

public MyDynObject(Dictionary<string, object> properties)
{
_properties = properties;
}

public override IEnumerable<string> GetDynamicMemberNames()
{
return _properties.Keys;
}

public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (_properties.ContainsKey(binder.Name))
{
result = _properties[binder.Name];
return true;
}
else
{
result = null;
return false;
}
}

public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (_properties.ContainsKey(binder.Name))
{
_properties[binder.Name] = value;
return true;
}
else
{
return false;
}
}
}

That way you just need:

var dyn = GetDynamicObject(new Dictionary<string, object>()
{
{"prop1", 12},
});

Console.WriteLine(dyn.prop1);
dyn.prop1 = 150;

Deriving from DynamicObject allows you to come up with your own strategy for handling these dynamic member requests, beware there be monsters here: the compiler will not be able to verify a lot of your dynamic calls and you won't get intellisense, so just keep that in mind.

How do I create dynamic properties in C#?

You might use a dictionary, say

Dictionary<string,object> properties;

I think in most cases where something similar is done, it's done like this.

In any case, you would not gain anything from creating a "real" property with set and get accessors, since it would be created only at run-time and you would not be using it in your code...

Here is an example, showing a possible implementation of filtering and sorting (no error checking):

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1 {

class ObjectWithProperties {
Dictionary<string, object> properties = new Dictionary<string,object>();

public object this[string name] {
get {
if (properties.ContainsKey(name)){
return properties[name];
}
return null;
}
set {
properties[name] = value;
}
}

}

class Comparer<T> : IComparer<ObjectWithProperties> where T : IComparable {

string m_attributeName;

public Comparer(string attributeName){
m_attributeName = attributeName;
}

public int Compare(ObjectWithProperties x, ObjectWithProperties y) {
return ((T)x[m_attributeName]).CompareTo((T)y[m_attributeName]);
}

}

class Program {

static void Main(string[] args) {

// create some objects and fill a list
var obj1 = new ObjectWithProperties();
obj1["test"] = 100;
var obj2 = new ObjectWithProperties();
obj2["test"] = 200;
var obj3 = new ObjectWithProperties();
obj3["test"] = 150;
var objects = new List<ObjectWithProperties>(new ObjectWithProperties[]{ obj1, obj2, obj3 });

// filtering:
Console.WriteLine("Filtering:");
var filtered = from obj in objects
where (int)obj["test"] >= 150
select obj;
foreach (var obj in filtered){
Console.WriteLine(obj["test"]);
}

// sorting:
Console.WriteLine("Sorting:");
Comparer<int> c = new Comparer<int>("test");
objects.Sort(c);
foreach (var obj in objects) {
Console.WriteLine(obj["test"]);
}
}

}
}

How to create dynamic properties

You can cast the ExpandoObject to an IDictionary<string,object> representing the mappings of property names to property values, and then manipulate those mappings:

IDictionary<string,object> expando = new ExpandoObject();
expando.Add("id", 1);

C# - Adding objects dynamically (adding dynamic property names)

Rather than creating an ExpandoObject or some other dynamic type, you could create a List<Dictionary<string, object>> where each Dictionary<string, object> contains the name/value pairs you want to serialize. Then serialize to JSON using Json.NET (or JavaScriptSerializer, though that is less flexible):

        var list = new List<Dictionary<string, object>>();

// Build a dictionary entry using a dictionary initializer: https://msdn.microsoft.com/en-us/library/bb531208.aspx
list.Add(new Dictionary<string, object> { { "ID", 1 }, {"Product", "Pie"}, {"Days", 1}, {"QTY", 65} });

// Build a dictionary entry incrementally
// See https://msdn.microsoft.com/en-us/library/xfhwa508%28v=vs.110%29.aspx
var dict = new Dictionary<string, object>();
dict["ID"] = 2;
dict["Product"] = "Melons";
dict["Days"] = 5;
dict["QTY"] = 12;
list.Add(dict);

Console.WriteLine(JsonConvert.SerializeObject(list, Formatting.Indented));
Console.WriteLine(new JavaScriptSerializer().Serialize(list));

The first outputs:

[
{
"ID": 1,
"Product": "Pie",
"Days": 1,
"QTY": 65
},
{
"ID": 2,
"Product": "Melons",
"Days": 5,
"QTY": 12
}
]

The second outputs the same without the indentation:

[{"ID":1,"Product":"Pie","Days":1,"QTY":65},{"ID":2,"Product":"Melons","Days":5,"QTY":12}]

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


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.

C# dynamically set property

objName.GetType().GetProperty("nameOfProperty").SetValue(objName, objValue, null)



Related Topics



Leave a reply



Submit