[英]How to access Properties of a class from a Generic Method - C#
我有一個具有以下屬性的三班
Class A
{
public int CustID { get; set; }
public string Name{ get; set; }
}
Class B
{
public int CustID { get; set; }
public string Age { get; set; }
}
我創建了一個接受所有這些類的通用方法。
public void ProceesData<T>(IList<T> param1, string date1)
{
Parallel.ForEach(T, (currentItem) =>
{
// I want to aceess CustID property of param1 and pass that value to another function
GetDetails(CustID );
RaiseRequest<T>(param1);
});
}
兩個類都存在CustID屬性(即A類和B類)。如何在此通用方法中訪問CustID屬性? 任何人都可以幫忙嗎
介紹界面:
interface ICust
{
public int CustID { get;}
}
class A : ICust
{
public int CustID { get; set; }
public string Name{ get; set; }
}
class B : ICust
{
public int CustID { get; set; }
public string Age { get; set; }
}
public void ProceesData<T>(IList<T> param1, string date1) where T : ICust
{
Parallel.ForEach(param1, (currentItem) =>
{
GetDetails(currentItem.CustID)
});
}
另一種可能性是使用System.Reflection
。
獲取PropertyInfo
從給定類型T
與屬性的名稱
通過該PropertyInfo
您可以使用GetValue
獲取該屬性的相應值。
這是一個小的測試程序來舉例說明:
public class ClassA
{
public int CustID { get; set; }
public string Name { get; set; }
}
public class ClassB
{
public int CustID { get; set; }
public string Age { get; set; }
}
public static void ProceesData<T>(IList<T> param1, string date1)
{
Parallel.ForEach(param1, (currentItem) =>
{
// I want to aceess CustID property of param1 and pass that value to another function
var value = typeof(T).GetProperty("CustID").GetValue(currentItem);
Console.WriteLine("Value: " + value);
});
}
public static void Main(string[] args)
{
List<ClassA> test = new List<ClassA>();
test.Add(new ClassA { CustID = 123 });
test.Add(new ClassA { CustID = 223 });
test.Add(new ClassA { CustID = 323 });
ProceesData<ClassA>(test, "test");
}
編輯
為了使其更具通用性,您可以將參數名稱傳遞給方法:
public static void ProceesData<T>(IList<T> param1, string date1, string parameter)
{
Parallel.ForEach(param1, (currentItem) =>
{
// I want to aceess CustID property of param1 and pass that value to another function
var value = typeof(T).GetProperty(parameter).GetValue(currentItem);
Console.WriteLine("Value: " + value);
});
}
現在,您可以決定要使用的參數:
ProceesData<ClassA>(test, "test", "Name");
要么
ProceesData<ClassB>(test, "test", "Age");
正如古斯曼(Gusman)所建議的,您可以通過在循環之前獲取一次PropertyInfo
來加快速度:
PropertyInfo pi = typeof(T).GetProperty(parameter);
Parallel.ForEach(param1, (currentItem) =>
{
// I want to aceess CustID property of param1 and pass that value to another function
var value = pi.GetValue(currentItem);
Console.WriteLine("Value: " + value);
});
編輯
顯然,性能似乎對您來說是個問題。 所以這是一個比較。 如果有時間等待,您可以自己嘗試。 如果我們根據屬性的訪問時間來衡量:
public static void ProceesDataD<T>(IList<T> param1, string date1)
{
Parallel.ForEach(param1, (currentItem) =>
{
dynamic obj = currentItem;
int custId = obj.CustID;
});
}
public static void ProceesData<T>(IList<T> param1, string date1) where T : ICust
{
Parallel.ForEach(param1, (currentItem) =>
{
var value = currentItem.CustID;
});
}
public static void ProceesData<T>(IList<T> param1, string date1, string parameter)
{
PropertyInfo pi = typeof(T).GetProperty(parameter);
Parallel.ForEach(param1, (currentItem) =>
{
var value = pi.GetValue(currentItem);
});
}
public static void Main(string[] args)
{
List<ClassA> test = new List<ClassA>();
List<A> testA = new List<A>();
Stopwatch st = new Stopwatch();
for (int i = 0; i < 10000; i++)
{
test.Add(new ClassA { CustID = 123, Name = "Me" });
testA.Add(new A { CustID = 123, Name = "Me" });
}
st.Start();
ProceesData<ClassA>(test, "test", "CustID");
st.Stop();
Console.WriteLine("Reflection: " + st.ElapsedMilliseconds);
st.Restart();
ProceesData<A>(testA, "test");
st.Stop();
Console.WriteLine("Interface: " + st.ElapsedMilliseconds);
st.Restart();
ProceesDataD<ClassA>(test, "test");
st.Stop();
Console.WriteLine("Dynamic: " + st.ElapsedMilliseconds);
}
免責聲明:使用代碼段一次只能測量一次時間。 不要按原樣運行程序,而是單獨運行每個測試。
如果您不能在現有類上引入接口或基類,則另一種方法是使用動態:
public void ProceesData<T>(IList<T> param1, string date1)
{
Parallel.ForEach(param1, (currentItem) =>
{
dynamic obj = currentItem;
int custId = obj.CustID ;
});
}
繼承將起作用
public abstract class ABBase
{
public int CustID { gete; set; }
}
public class A : ABBase
{
public string Name { get; set; }
}
public class B : ABBase
{
public string Age { get; set; }
}
然后,而不是使用通用方法
public void ProcessData(IList<ABBase> param1, string date)
{
Parallel.ForEach(T, (currentItem) =>
{
GetDetails(CustID )
});
}
動態
應該可以解決此問題,請勿投射或轉圈。
List<T> products = new List<T>();
foreach (dynamic prod in products)
{
prod.ShopCategoryID = 1 ; // give you access to props
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.