【问题标题】:Dynamically pass object type to generic method动态地将对象类型传递给泛型方法
【发布时间】:2014-11-23 13:45:42
【问题描述】:

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

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

【问题讨论】:

    标签: c# generics


    【解决方案1】:

    你可以这样做。

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

    【讨论】:

    • 该问题已将myFoo 等声明为object,因此类型推断在这里无济于事。该问题专门讨论了该案例是运行时场景(OP 称为动态)
    【解决方案2】:

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

    public static object getItem(object obj, string _Value)
    

    【讨论】:

      猜你喜欢
      • 2017-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多