2

我想通过一些适配器,基于属性值访问一个类的功能。所有函数都具有相同的原型
,我想这样做的方式是声明这样的字典:

Dictionary<key_values, Delegate_of_Functions>

其中key_values包含标识函数的值的类,并且Delegate_of_Functions是函数类型的委托。

现在,我尝试执行以下操作:

Functions = new Dictionary<string, function>();

var a = from Fun in typeof(TheFunctionsContainer).GetMethods()
        where Fun.GetCustomAttributes(typeof(The_Attribute), true).Length != 0
        select Fun;

foreach (var c in a)
{
  Functions.Add(
    c.GetCustomAttributes(true).OfType<The_Attribute>().First().key,
    new function(c)); // this line dose not compile
}

我的问题是:

  • 如何让未编译的行编译?
  • 有一个更好的方法吗?
4

2 回答 2

2

鉴于这function是一个代表

delegate void function();

您可以使用Delegate.CreateDelegate创建委托的方法

var Functions = new Dictionary<string, function>();

var a = typeof(TheFunctionsContainer).GetMethods().Where(f => f.GetCustomAttributes(typeof(The_Attribute), true).Any());

foreach (var c in a)
{
    Functions.Add(
      c.GetCustomAttributes(true).OfType<The_Attribute>().First().key,
      (function)Delegate.CreateDelegate(typeof(function), c)); 
}

如果要在实例上执行非静态方法,则必须提供您希望方法调用的实例Delegate.CreateDelegate

(function)Delegate.CreateDelegate(typeof(function), yourInstance, c)

或者只是看 svicks 评论:-)

于 2012-08-28T12:58:51.663 回答
-1

一种直接的方法是在您找到的Invoke方法上调用该方法。您可以在添加到您的字典中的匿名代表中执行此操作。

你说你所有的函数都有相同的原型(在 C# 中通常称为签名),但由于你没有指出签名是什么,我将简单地假设一个 void 方法,它接受一个字符串和一个整数(由在我下面的Action<string, int>示例代码中)。我相信您可以更改代码以使其适合您:-)

中的每个元素a,即循环中的c每个元素,都是类型:foreachMethodInfo

var Function = new Dictionary<string, Action<string, int>>();

// your code for discovering the suitable functions and filling a

foreach (var c in a) {
    Functions.Add(c.GetCustomAttributes(true).OfType<The_Attribute>().First().key,
      (s, i) => {
          c.Invoke(null, new object[] { s, i });
      });
}

不过,在向该字典添加任何内容之前,您可能需要检查该MethodInfo实例是否表明该方法确实具有所需的签名。否则,有人可能有意或无意地使用该属性标记具有不同签名的方法,并且调用Invoke将失败。

于 2012-08-28T12:57:01.203 回答