![](/img/trans.png)
[英]Set property on a derived class of List<T> instantiated at runtime using reflection
[英]Using reflection to set List<dynamic> to List<T>
說,我在一個類中有這些屬性:
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 [Toyota]”。
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);
}
任何建議,不勝感激!
請嘗試這樣的事情
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);
}
我認為主要問題是您的軟件設計。 我不會以這種方式使用動態。
我會創建一個品牌級的。 如果要使用動態,請嘗試以下操作:
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; }
填寫數據時,只需在品牌列表中添加一個新的動態品牌,然后只需添加所需的成員即可。
編輯 :動態不是一個很好的解決方案,為您的問題。 我會考慮完全不同的結構。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.