在运行时动态添加 C# 属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15819720/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dynamically Add C# Properties at Runtime
提问by Paul Grimshaw
I know there are some questions that address this, but the answers usually follow along the lines of recommending a Dictionary or Collection of parameters, which doesn't work in my situation.
我知道有一些问题可以解决这个问题,但答案通常遵循推荐字典或参数集合的方式,这在我的情况下不起作用。
I am using a library that works through reflection to do lots of clever things with objects with properties. This works with defined classes, as well as dynamic classes. I need to take this one step further and do something along these lines:
我正在使用一个通过反射工作的库来对具有属性的对象做很多聪明的事情。这适用于定义的类以及动态类。我需要更进一步,并按照以下方式做一些事情:
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;
}
The library works fine with a dynamic variable type, with properties assigned manually. However I don't know how many or what properties will be added beforehand.
该库可以很好地处理动态变量类型,并手动分配属性。但是我不知道会预先添加多少或哪些属性。
采纳答案by Clint
Have you taken a look at ExpandoObject?
你看过 ExpandoObject 吗?
见:http: //blogs.msdn.com/b/csharpfaq/archive/2009/10/01/dynamic-in-c-4-0-introducing-the-expandoobject.aspx
From MSDN:
来自 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").
ExpandoObject 类使您能够在运行时添加和删除其实例的成员,以及设置和获取这些成员的值。此类支持动态绑定,这使您可以使用像 sampleObject.sampleMember 这样的标准语法,而不是像 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 notbe able to verify a lot of your dynamic calls and you won't get intellisense, so just keep that in mind.
从 DynamicObject 派生允许您想出自己的策略来处理这些动态成员请求,请注意这里有怪物:编译器将无法验证您的大量动态调用,您将无法获得智能感知,因此请保持记在心上。
回答by Paul Grimshaw
Thanks @Clint for the great answer:
感谢@Clint 的精彩回答:
Just wanted to highlight how easy it was to solve this using the Expando Object:
只是想强调使用 Expando 对象解决这个问题是多么容易:
var dynamicObject = new ExpandoObject() as IDictionary<string, Object>;
foreach (var property in properties) {
dynamicObject.Add(property.Key,property.Value);
}
回答by Khurshid Ali
you could deserialize your json string into a dictionary and then add new properties then serialize it.
您可以将 json 字符串反序列化为字典,然后添加新属性然后将其序列化。
var jsonString = @"{}";
var jsonDoc = JsonSerializer.Deserialize<Dictionary<string, object>>(jsonString);
jsonDoc.Add("Name", "Khurshid Ali");
Console.WriteLine(JsonSerializer.Serialize(jsonDoc));