动态将对象类型传递给泛型方法

本文关键字:泛型方法 类型 对象 动态 | 更新日期: 2023-09-27 18:31:29

我一直在玩泛型,并试图弄清楚如何(如果可能的话)通过动态传递对象来跨多个类使用单个方法。

我有几个课程,Foo和Bar如下:

[Serializable()]
public class Foo
{
    private string m_Code;
    private Bar m_Bar = new Bar();
    public string Code
    {
        get { return m_Code; }
        set { m_Code = value; }
    }
    public Bar Bar
    {
        get { return m_Bar; }
        set { m_Bar = value; }
    }
}

[Serializable()]
public class Bar
{
    private string m_Name;
    public string Name
    {
        get { return m_Name; }
        set { m_Name = value; }
    }
}

如果我用一些虚拟数据填充我的类:

Foo.Code = "myFoo";
Foo.Bar.Name = "myBar";

我有一个通用方法可以从类返回值:

public static object getItem<T>(T obj, string _Value)
{
try
{
    object _Resolved = null;
    _Resolved = obj.GetType().GetProperty(_Value).GetValue(obj, null);
    return _Resolved;
}
catch (Exception ex)
{
    return null;
}
}

像下面这样调用我的 getItem 方法工作正常。

string FooCode = Convert.ToString(getItem<Foo>(myFoo, "Code")) // returns "myFoo"
string BarName = Convert.ToString(getItem<Bar>(myFoo.Bar, "Name")) // returns "myBar"

我好奇的是,是否有一种通用的方法可以通过定义对象来解决我的getItem方法?

例如:

object myObject = Foo;
string FooCode = Convert.ToString(getItem<typeof(myObject)>(myObject, "Code")) // And this would returns "myFoo"

或:

object myObject = Bar;
string BarName = Convert.ToString(getItem<typeof(myObject)>(myObject, "Name")) // And this would returns "myBar"

动态将对象类型传递给泛型方法

你可以

这样做。

string FooCode = Convert.ToString(getItem(myFoo, "Code")) // returns "myFoo"
string BarName = Convert.ToString(getItem(myFoo.Bar, "Name")) // returns "myBar"

它会自动推断对象的类型。如果要在运行时从对象类型调用泛型方法,则必须使用反射创建泛型方法。下面是示例。

public class Program 
{
static void Main(string[] args)
        {
            Foo myFoo = new Foo();
            myFoo.Bar = new Bar();
            myFoo.Bar.Name = "Jinal";
            myFoo.Code = "Ths is test";
            // By Using infer
            string FooCode = Convert.ToString(getItem(myFoo, "Code")); // returns "myFoo"
            string BarName = Convert.ToString(getItem(myFoo.Bar, "Name"));
            // Using Reflection
            Type ex = typeof(Program);
            MethodInfo mi = ex.GetMethod("getItem");
            object foo = myFoo;
            var methodgetItem =  mi.MakeGenericMethod(foo.GetType());
            string result = Convert.ToString(methodgetItem.Invoke(null, new object[]{foo , "Code"}));
            object bar = myFoo.Bar;
            var methodgetItem1 = mi.MakeGenericMethod(bar.GetType());
            string result1 = Convert.ToString(methodgetItem1.Invoke(null, new object[] {bar , "Name" }));
            Console.ReadLine();
        }
        public static object getItem<T>(T obj, string _Value)
        {
            try
            {
                object _Resolved = null;
                _Resolved = obj.GetType().GetProperty(_Value).GetValue(obj, null);
                return _Resolved;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
 }

getItem 方法中,您没有使用 Type 参数 T 。对于您的特定问题(在编译时不知道obj类型),您可以简单地将方法定义为如下 -

public static object getItem(object obj, string _Value)