c# - 类库中的反射 GetMethod 问题(可移植)

标签 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 获取函数,编译器生成错误“类型不包含 GetMethod 的定义...”

请指教。 谢谢!

更新:编译错误 enter image description here

单例更新:

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

}

最佳答案

首先,大多数 PCL 配置文件都使用 TypeInfo有关类型信息,请参见例如herehere . TypeInfo还带有一组略有不同的方法。

所以,而不是写

<罢工> typeof(Class1).GetMethod(i)

你应该这样写:

typeof(Class1).GetTypeInfo().GetDeclaredMethod(i)

但是即使你用上面的表达式得到MethodInfo ,您不能(据我所知)立即将此对象转换为 myFunction委托(delegate)。

解决此问题的一种方法是使用 expression trees .然后你需要制定一个 Expression<myFunction>您将编译成 myFunction 的对象委托(delegate)。

我认为你可以这样做:

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

objExprobject o 的表示参数

ParameterExpression objExpr = Expression.Parameter(typeof(object));

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

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

关于c# - 类库中的反射 GetMethod 问题(可移植),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35466195/

相关文章:

c# - 3DES 加密实现报告来自 C# 实现的不同输出

c# - 处理流时 C# 中的 NullReferenceException?

.net - Assembly.GetCallingAssembly 在 WinRT 上不受支持,但适用于可移植类库?

c# - 在 Pin Map 控件 Xamarin 表单 pcl 上调用单击事件

c# - Cosmos DB 中的并行更新数据

c# - 如何在反序列化对象后创建用于加载 XML 文件的 XDocument 实例?

iphone - 两个 View Controller 可以成为彼此的委托(delegate)吗?

c# - 订阅 Func 事件后不会调用协程方法

ios - 在 arc : EXC_BAD_ACCESS 中消失的 self.delegate

等效于 System.Diagnostics.StackTrace 的 C# 可移植类库