类库(Portable)中的反射GetMethod问题

时间:2016-02-17 19:42:15

标签: c# delegates portable-class-library

我有一个类库,我在其中定义了一些函数f1,f2,我想将它们放在字典中以便稍后按名称调用。但是,反射Type.GetMethod似乎没有在类库中定义,即使我使用的是System.Reflection。你能建议一个解决方法吗?

这是我用来举例说明的简单代码

   public class Class1
    {
        public delegate int myFunction(object o);
        private Dictionary<string, myFunction> list = new Dictionary<string, myFunction>();
        public Class1()
        {
            string[] n = { "f1", "f2" };
            MethodInfo mInfo;
            foreach (var i in n)
            {
                mInfo = typeof(Class1).GetMethod(i);
            }

            list.Add("f1", f1);
            list.Add("f2", f2);
        }
        public  int f1(object o)
        {
            System.Diagnostics.Debug.WriteLine("f1: parameter is {0} " ,o);
            return 0;
        }
        public int f2(object o)
        {
            System.Diagnostics.Debug.WriteLine("f2: parameter is {0} ", o);
            return 0;
        }
    }

我的初衷是将我的所有功能都放在我的词典列表中。我可以手动添加:

                list.Add("f1", f1);
                list.Add("f2", f2);

但是当我声明一个带有函数名称的字符串数组时,使用GetMethod来获取函数,编译器生成错误&#34; Type不包含GetMethod的定义......

请指教。 谢谢!

更新:编译错误 enter image description here

使用Singleton更新:

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

namespace ClassLibrary1
{
    public sealed class Class1
    {
        public delegate int myFunction(object o);
        public Dictionary<string, myFunction> list = new Dictionary<string, myFunction>();
        private static readonly Class1 _instance = new Class1();
        static Class1()
        {
        }
        public Class1()
        {
            string[] n = { "f1", "f2" };
            MethodInfo mInfo;
            foreach (var i in n)
            {
                mInfo = typeof(Class1).GetTypeInfo().GetDeclaredMethod(i);
                //NewExpression constrExpr = Expression.New(typeof(Class1).GetTypeInfo().DeclaredConstructors.Single(ci => ci.GetParameters().Length == 0));
                ParameterExpression objExpr = Expression.Parameter(typeof(object));
                Expression<myFunction> expr = Expression.Lambda<myFunction>(Expression.Call(null, mInfo, objExpr), objExpr);
                //Expression<myFunction> expr = Expression.Lambda<myFunction>(Expression.Call(constrExpr, mInfo, objExpr), objExpr);
                list.Add(i, expr.Compile());
            }

            list.Add("f11", f1);
            list.Add("f21", f2);
        }
        public static Class1 Instance
        {
            get
            {
                return _instance;
            }
        }
        public int f1(object o)
        {
            System.Diagnostics.Debug.WriteLine("f1: parameter is {0} ", o);
            return 0;
        }
        public int f2(object o)
        {
            System.Diagnostics.Debug.WriteLine("f2: parameter is {0} ", o);
            return 0;
        }
    }

}

1 个答案:

答案 0 :(得分:3)

首先,大多数PCL配置文件都使用TypeInfo来获取类型信息,例如, hereheretypeof(Class1).GetMethod(i)还附带了一组略有不同的方法。

所以,而不是写

<击> typeof(Class1).GetTypeInfo().GetDeclaredMethod(i)

你应这样写:

MethodInfo

但即使您使用上述表达式获取myFunction,您也不能(据我所知)立即将此对象转换为Expression<myFunction>委托。

解决此问题的一种方法是使用expression trees。然后,您需要制定一个myFunction对象,然后将其编译为Expression<myFunction> expr = Expression.Lambda<myFunction>( Expression.Call( constrExpr, typeof(Class1).GetTypeInfo().GetDeclaredMethod(i), objExpr), objExpr); list.Add(i, expr.Compile()); 代理。

我认为你可以这样做:

constrExpr

其中Class1是使用默认构造函数创建NewExpression constrExpr = Expression.New( typeof(Class1).GetTypeInfo().DeclaredConstructors .Single(ci => ci.GetParameters().Length == 0)); 实例的表达式

objExpr

object o表示ParameterExpression objExpr = Expression.Parameter(typeof(object)); 参数

int i = list["f1"]("hello");
int j = list["f2"](20.0);

通过这些更改,您应该能够在字典中调用任意方法,如下所示:

App.js