我有一个具有以下属性的三个类
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属性?任何人都可以帮忙吗
答案 0 :(得分:13)
介绍界面:
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)
});
}
答案 1 :(得分:7)
另一种可能性是使用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);
}
免责声明:使用代码段落来衡量当时只有一个时间。不要按原样运行程序,而是每次单独测试。
答案 2 :(得分:4)
如果您不能在现有类上引入接口或基类,则另一种方法是使用dynamic:
public void ProceesData<T>(IList<T> param1, string date1)
{
Parallel.ForEach(param1, (currentItem) =>
{
dynamic obj = currentItem;
int custId = obj.CustID ;
});
}
答案 3 :(得分:1)
继承将起作用
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 )
});
}
答案 4 :(得分:0)
动态
应该解决此问题,请勿投射或绕圈。
List<T> products = new List<T>();
foreach (dynamic prod in products)
{
prod.ShopCategoryID = 1 ; // give you access to props
}