c# DynamicObject class 来自循环的动态属性
c# DynamicObject class dynamic properties from loop
所以我创建了一个继承 DynamicObject
的 class
public class MyDynamicObject : DynamicObject{
private Dictionary<string, object> Fields = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return Fields.TryGetValue(binder.Name, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
Fields[binder.Name] = value;
return true;
}
}
并在此处称其为 class
public class Program
{
public static void Main()
{
dynamic person = new MyDynamicObject();
person.firstname = "Hello";
Console.WriteLine(person.firstname);
}
}
当然可以。但是我需要从
这样的字符串数组创建属性
string[] fields = new string[]{"taxid","newcol","addrs","gender"};
dynamic person = new MyDynamicObject();
foreach(var f in fields)
{
person.f = "hello";
}
因此输出将是 person.taxi、person.newcol、person.addrs、person.gender
这可能吗?
以某种方式公开 Fields
字典,或者(更好)一种允许通过名称显式设置 属性 的方法。
请注意 ExpandoObject
已经这样做了,因为它可以转换为 IDictionary<string, object>
然后你
ExpandoObject eo = new ExpandoObject();
IDictionary<string, object> dict = eo;
dynamic d = eo;
dict["MyProperty"] = 42;
Console.WriteLine(d.MyProperty); // 42
如果你不能只使用ExpandoObject
本身,你可以复制它的方法。
好的,根据@Jon Hanna 的建议,我想出了一个符合我要求的解决方案。我创建了一个接受名称的新 Add 方法。以下是我使用的更新代码。
public class DynamicFormData : DynamicObject
{
private Dictionary<string, object> Fields = new Dictionary<string, object>();
public int Count { get { return Fields.Keys.Count; } }
public void Add(string name, string val = null)
{
if (!Fields.ContainsKey(name))
{
Fields.Add(name, val);
}
else
{
Fields[name] = val;
}
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (Fields.ContainsKey(binder.Name))
{
result = Fields[binder.Name];
return true;
}
return base.TryGetMember(binder, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (!Fields.ContainsKey(binder.Name))
{
Fields.Add(binder.Name, value);
}
else
{
Fields[binder.Name] = value;
}
return true;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
if (Fields.ContainsKey(binder.Name) &&
Fields[binder.Name] is Delegate)
{
Delegate del = Fields[binder.Name] as Delegate;
result = del.DynamicInvoke(args);
return true;
}
return base.TryInvokeMember(binder, args, out result);
}
}
那我就这么叫吧
string[] fields = new string[]{"taxid","newcol","addrs","gender"};
dynamic formData = new DynamicFormData();
foreach(string field in fields)
{
formData.Add(field, null);
}
所以我创建了一个继承 DynamicObject
的 classpublic class MyDynamicObject : DynamicObject{
private Dictionary<string, object> Fields = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return Fields.TryGetValue(binder.Name, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
Fields[binder.Name] = value;
return true;
}
}
并在此处称其为 class
public class Program
{
public static void Main()
{
dynamic person = new MyDynamicObject();
person.firstname = "Hello";
Console.WriteLine(person.firstname);
}
}
当然可以。但是我需要从
这样的字符串数组创建属性string[] fields = new string[]{"taxid","newcol","addrs","gender"};
dynamic person = new MyDynamicObject();
foreach(var f in fields)
{
person.f = "hello";
}
因此输出将是 person.taxi、person.newcol、person.addrs、person.gender
这可能吗?
以某种方式公开 Fields
字典,或者(更好)一种允许通过名称显式设置 属性 的方法。
请注意 ExpandoObject
已经这样做了,因为它可以转换为 IDictionary<string, object>
然后你
ExpandoObject eo = new ExpandoObject();
IDictionary<string, object> dict = eo;
dynamic d = eo;
dict["MyProperty"] = 42;
Console.WriteLine(d.MyProperty); // 42
如果你不能只使用ExpandoObject
本身,你可以复制它的方法。
好的,根据@Jon Hanna 的建议,我想出了一个符合我要求的解决方案。我创建了一个接受名称的新 Add 方法。以下是我使用的更新代码。
public class DynamicFormData : DynamicObject
{
private Dictionary<string, object> Fields = new Dictionary<string, object>();
public int Count { get { return Fields.Keys.Count; } }
public void Add(string name, string val = null)
{
if (!Fields.ContainsKey(name))
{
Fields.Add(name, val);
}
else
{
Fields[name] = val;
}
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (Fields.ContainsKey(binder.Name))
{
result = Fields[binder.Name];
return true;
}
return base.TryGetMember(binder, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (!Fields.ContainsKey(binder.Name))
{
Fields.Add(binder.Name, value);
}
else
{
Fields[binder.Name] = value;
}
return true;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
if (Fields.ContainsKey(binder.Name) &&
Fields[binder.Name] is Delegate)
{
Delegate del = Fields[binder.Name] as Delegate;
result = del.DynamicInvoke(args);
return true;
}
return base.TryInvokeMember(binder, args, out result);
}
}
那我就这么叫吧
string[] fields = new string[]{"taxid","newcol","addrs","gender"};
dynamic formData = new DynamicFormData();
foreach(string field in fields)
{
formData.Add(field, null);
}