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

时间:2014-11-23 02:24:12

标签: c# generics

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

我有几个课程,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"

2 个答案:

答案 0 :(得分:2)

你可以这样做。

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

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

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

答案 1 :(得分:0)

getItem方法中,您没有使用Type参数T。 对于您的特定问题(编译时未知obj的类型),您可以按如下方式定义方法 -

public static object getItem(object obj, string _Value)