【问题标题】:How to call a generic method through reflection [duplicate]如何通过反射调用泛型方法[重复]
【发布时间】:2009-12-21 16:52:26
【问题描述】:

是否可以通过反射调用具有“显式类型参数”<S> 定义的方法
例如oObject.Cast<S>()?

在哪里:

IList <P> oObject = new List <P>();

我试过了

oObject.getType().InvokeMember( "Cast", BindingFlags.InvokeMethod, null, oObject, null)

但它不起作用,有人知道为什么吗?


这是完整的测试代码,但仍然无法正常工作。最后一行总是产生异常。有没有可能让它发挥作用?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace reflection_tester
{
    class CBase
    {
        public string Ja = "I am the base";
    }

    class MyClass01 : CBase
    {
        public string _ID;

        public string ID
        {
            get { return _ID; }
            set { _ID = value; }
        }
    }

    class Program
    {

        public static object wrapper()
        {
            //return a list of classes MyClass01

            IList<MyClass01> lstClass01 = new List<MyClass01>();

            MyClass01 oClass01a = new MyClass01();
            oClass01a.ID = "1";

            MyClass01 oClass01b = new MyClass01();
            oClass01b.ID = "2";

            lstClass01.Add(oClass01a);
            lstClass01.Add(oClass01b);

            return lstClass01;
        }

        static void Main(string[] args)
        {

            MyClass01 oMy1 = new MyClass01();
            oMy1._ID = "1";

            MyClass01 oMy2 = new MyClass01();
            oMy2._ID = "3";

            IList<MyClass01> oListType01 = new List<MyClass01>();

            oListType01.Add(oMy1);
            oListType01.Add(oMy2);

            object oObjectType = new object();

            oObjectType = oListType01;

            /* this works */
            IEnumerable<CBase> enumList = oListType01.Cast<CBase>();

            MethodInfo mInfo = typeof(System.Linq.Enumerable).GetMethod("Cast", new[] { typeof(System.Collections.IEnumerable) }).MakeGenericMethod(typeof(CBase));

            /* this does not work, why ? throws exception */
            IEnumerable<CBase> enumThroughObject = (IEnumerable<CBase>)mInfo.Invoke(oObjectType, null);

            return;
        }
    }
}

【问题讨论】:

    标签: c# reflection generics


    【解决方案1】:

    Cast 扩展方法存在于 Enumerable 类上,您需要调用 MakeGenericMethod:

    typeof(System.Linq.Enumerable)
        .GetMethod("Cast", new []{typeof(System.Collections.IEnumerable)})
        .MakeGenericMethod(typeof(S))
        .Invoke(null, new object[] { oObjectType })
    

    更新:因为方法是静态的,所以Invoke的第一个参数应该是null

    【讨论】:

    • Invoke 函数不接受一个参数,所以如果我将第二个参数设置为“null”,我会遇到异常。有什么线索吗?
    • 异常获取是:参数数量无效。
    • Enumerable.Cast&lt;T&gt;() 不接受任何“参数”。本例中给出的参数是您要调用扩展方法 Cast 的对象。
    • 但是没有只有一个参数的调用!?
    • @milan:抱歉,@Rob 的代码似乎有点不正确。根据 MSDN,您可以致电 .Invoke(null, oObject),因为 Cast 是静态的。 msdn.microsoft.com/en-us/library/a89hcwhh.aspx
    【解决方案2】:

    我想你在找Type.MakeGenericType

    【讨论】:

    • 很抱歉,这么简短的解释我看不懂,你能写一些代码以便更好地理解吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-27
    相关资源
    最近更新 更多