在运行时dynamic添加C#属性

我知道有一些问题可以解决这个问题,但答案通常遵循推荐字典或参数集合的方式,这在我的情况下是行不通的。

我正在使用一个通过reflection工作的库来完成许多具有属性的对象的聪明事情。 这与定义的类以及dynamic类一起工作。 我需要更进一步,沿着这些路线做些事情:

public static object GetDynamicObject(Dictionary<string,object> properties) { var myObject = new object(); foreach (var property in properties) { //This next line obviously doesn't work... myObject.AddProperty(property.Key,property.Value); } return myObject; } public void Main() { var properties = new Dictionary<string,object>(); properties.Add("Property1",aCustomClassInstance); properties.Add("Property2","TestString2"); var myObject = GetDynamicObject(properties); //Then use them like this (or rather the plug in uses them through reflection) var customClass = myObject.Property1; var myString = myObject.Property2; } 

该库工作正常,dynamicvariablestypes,手动分配属性。 但是我不知道预先添加了多less或什么属性。

你有没有看过ExpandoObject?

请参阅: http : //blogs.msdn.com/b/csharpfaq/archive/2009/10/01/dynamic-in-c-4-0-introducing-the-expandoobject.aspx

来自MSDN:

ExpandoObject类使您可以在运行时添加和删除其实例的成员,并设置和获取这些成员的值。 该类支持dynamic绑定,使您可以使用标准语法(如sampleObject.sampleMember),而不是使用更复杂的语法(如sampleObject.GetAttribute(“sampleMember”))。

允许你做一些很酷的事情,比如:

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

根据您的实际代码,您可能会更感兴趣:

 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; } } } 

这样你只需要:

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

通过从DynamicObject派生出来,您可以提出自己的处理这些dynamic成员请求的策略,请注意这里有怪物:编译器将无法validation很多dynamic调用,并且不会获得智能感知,所以只需保留这一点。

感谢@克林特的伟大的答案:

只是想强调使用Expando对象来解决这个问题是多么简单:

 public static dynamic GetDynamicObject(Dictionary<string,object> properties) { var dynamicObject = new ExpandoObject() as IDictionary<string, Object>; foreach (var property in properties) { dynamicObject.Add(property.Key,property.Value); } return dynamicObject; }