如何从泛型方法访问类的属性-C# [英] How to access Properties of a class from a Generic Method - C#

查看:282
本文介绍了如何从泛型方法访问类的属性-C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有以下特性的三类

I have a three class which is having following properties

Class A
{
    public int CustID { get; set; }
    public string Name{ get; set; }
}

Class B
{
    public int CustID { get; set; }
    public string Age { get; set; }
}

我创建了一个接受所有这些类的通用方法.

I created one generic method which accepts all these classes.

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属性?有人可以帮忙吗

CustID property is present in Both classes(ie in Class A& Class B).How can i access CustID property in this generic method ? Can anyone help on this

推荐答案

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

Another possibility would be to use System.Reflection.

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

  1. Get the PropertyInfo from the given type T with the name of the property

使用该PropertyInfo,您可以使用GetValue获取该属性的相应值.

with that PropertyInfo you can use GetValue to get the corresponding value of that property.

这是一个小的测试程序,可以证明这一点:

Here is a small test programm to exemplify this:

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");
}

编辑

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

To make it a little more universal you could just pass the parameter name into the method:

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);
    });
}

现在,您可以决定要使用什么参数:

Now you can decide what parameter you want to use:

 ProceesData<ClassA>(test, "test", "Name");

 ProceesData<ClassB>(test, "test", "Age");

按照Gusman的建议,您可以通过在循环前获取一次PropertyInfo来加快速度:

As suggested by Gusman you could speed up a little by getting the PropertyInfo just once before the loop:

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);
});

编辑

显然,性能似乎对您来说是个问题.所以这是一个比较.如果有时间等待,您可以自己尝试.如果我们衡量该属性的访问时间:

Apparently performance seems to be an issue for you. So here is a comparison. You can try it on your own if you have a minute to wait. If we measure on the access time of the property:

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);
}

免责声明:使用代码段一次只能测量一次时间.不要按原样运行程序,而是每个测试都是自己的.

Disclaimer: use the code passages to measure the time only one at the time. Do not run the program as it is but each single test on it's own.

这篇关于如何从泛型方法访问类的属性-C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆