如何从通用方法访问类的属性 – 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; } } 

我创建了一个接受所有这些类的generics方法。

  public void ProceesData(IList 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(param1); }); } 

CustID属性存在于两个类中(即在A类和B类中)。如何在此generics方法中访问CustID属性? 任何人都可以帮助这个

另一种可能性是使用System.Reflection

  1. 从给定类型T获取具有PropertyInfo名称的PropertyInfo

  2. 使用该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(IList 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 test = new List(); test.Add(new ClassA { CustID = 123 }); test.Add(new ClassA { CustID = 223 }); test.Add(new ClassA { CustID = 323 }); ProceesData(test, "test"); } 

编辑

为了使它更具通用性,您可以将参数名称传递给方法:

 public static void ProceesData(IList 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(test, "test", "Name"); 

要么

  ProceesData(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(IList param1, string date1) { Parallel.ForEach(param1, (currentItem) => { dynamic obj = currentItem; int custId = obj.CustID; }); } public static void ProceesData(IList param1, string date1) where T : ICust { Parallel.ForEach(param1, (currentItem) => { var value = currentItem.CustID; }); } public static void ProceesData(IList 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 test = new List(); List testA = new List(); 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(test, "test", "CustID"); st.Stop(); Console.WriteLine("Reflection: " + st.ElapsedMilliseconds); st.Restart(); ProceesData(testA, "test"); st.Stop(); Console.WriteLine("Interface: " + st.ElapsedMilliseconds); st.Restart(); ProceesDataD(test, "test"); st.Stop(); Console.WriteLine("Dynamic: " + st.ElapsedMilliseconds); } 

免责声明:使用代码段落来衡量当时只有一个时间。 不要按原样运行程序,而是每次单独测试。

介绍界面:

  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(IList param1, string date1) where T : ICust { Parallel.ForEach(param1, (currentItem) => { GetDetails(currentItem.CustID) }); } 

如果您不能在现有类上引入接口或基类,则另一种方法是使用dynamic:

 public void ProceesData(IList param1, string date1) { Parallel.ForEach(param1, (currentItem) => { dynamic obj = currentItem; int custId = obj.CustID ; }); } 

inheritance会起作用

 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 param1, string date) { Parallel.ForEach(T, (currentItem) => { GetDetails(CustID ) }); }