说,我在课堂上有这些属性:
public class Example
{
public List<Toyota> listToyota;
public List<Honda> listHonda;
public List<Huyndai> listHuyndai;
...
...
}
如果有新的汽车品牌,将会有更多的房产。每个品牌都是一张桌子。
通常,我会这样做以从表中获取数据:
Example result = new Example();
switch (brandname)
{
case "Toyota":
result.listToyota = * select table from context * ;
break;
case "Honda":
result.listHonda = * select table from context * ;
break;
...
}
此外,当有新品牌时,我将不得不添加更多代码。我发现这非常烦人/耗时,并决定转向动态方法。我已成功地动态获取表格:
tblName = "Toyota";
IEnumerable<dynamic> table = typeof(MyContext).GetProperty(tblName).GetValue(context, null) as IEnumerable<dynamic>;
但我无法动态设置属性值,在本例中为listToyota
:
query = (from a in table select a).ToList() as List<dynamic>;
SetPropertyValue(result, "listToyota", query);
我收到了这个错误:
类型为'System.Collections.Generic.List1 [System.Object]'的对象 无法转换为类型 'System.Collections.Generic.List1 [丰田]'。
SetPropertyValue
使用System.Reflection
是一个非常简单的函数:
static void SetPropertyValue(object p, string propName, object value)
{
Type t = p.GetType();
System.Reflection.PropertyInfo info = t.GetProperty(propName);
if (info == null)
return;
if (!info.CanWrite)
return;
info.SetValue(p, value, null);
}
非常感谢任何建议!
答案 0 :(得分:2)
请尝试这样的事情
static void SetPropertyValue(object p, string propName, object value)
{
Type t = p.GetType();
System.Reflection.PropertyInfo info = t.GetProperty(propName);
if (info == null)
return;
if (!info.CanWrite)
return;
var elemtype = info.PropertyType.GetElementType();
var castmethod = typeof(Enumerable).GetMethod("Cast", BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elemtype);
var tolist = typeof(Enumerable).GetMethod("ToList", BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elemtype);
var collection = castmethod.Invoke(null, new object[] { value });
var list = tolist.Invoke(null, new object[] { collection });
info.SetValue(p, list, null);
}
答案 1 :(得分:-1)
我认为主要问题是您的软件设计。我不会以这种方式使用动态。
我会创建一个Brand-Class。如果你想使用动态,尝试这样的事情:
public class DynamicBrand : DynamicObject
{
private IDictionary<string, object> myDynamicValues;
public DynamicBrand()
: base()
{
myDynamicValues = new Dictionary<string, object>();
}
public void AddMember(string Name, object Value)
{
if (!myDynamicValues.ContainsKey(Name.Trim().ToLower()))
{
myDynamicValues.Add(Name.ToLower().Trim(), Value);
}
else
{
throw new Exception("The Member with the Name: " + Name + " already exists!");
}
}
public override bool TrySetMember(SetMemberBinder Binder, object Value)
{
if (myDynamicValues.ContainsKey(Binder.Name.ToLower()))
{
myDynamicValues[Binder.Name.ToLower()] = Value;
return true;
}
else
{
myDynamicValues.Add(Binder.Name.ToLower(), Value);
}
return true;
}
publc override bool TryGetMember(GetMemberBinder Binder, out object Result)
{
if (myDynamicValues.ContainsKey(Binder.Name.ToLower()))
{
Result = myDynamicValues[Binder.Name.ToLower()];
return true;
}
else
{
Result = null;
return false;
}
}
我会改变你的示例类
public class Example
{
// string = brand-name; list = list of dynamic brand items
public Dictionary<string, List<DynamicBrand>> brands;
}
当您填写数据时,只需在品牌列表中添加一个新的动态品牌,然后只需添加您需要的成员。
编辑:动态不是解决您问题的绝佳解决方案。我会考虑一个完全不同的结构。