基于属性值在c#中查找函数

时间:2012-08-28 12:41:57

标签: c# linq reflection

我想通过某个适配器根据属性值访问类的功能。所有功能都有相同的原型
我认为这样做的方式是声明一个类似的字典:

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
}

我的问题是:

  • 如何获取不编译的行?
  • 有更好的方法吗?

2 个答案:

答案 0 :(得分: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评论: - )

答案 1 :(得分:-1)

执行此操作的直接方法是在找到的方法上调用Invoke method。您可以在添加到词典中的匿名代理中执行此操作。

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

a中的每个元素,即c循环中的每个foreach都属于MethodInfo类型:

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的调用将失败。