4

我想要一个字典,它使用字符串作为键和代表方法的东西,所有这些都可能有不同的签名,作为值。从这个东西,如果方法不是静态的,我应该能够访问MethodInfo对象的一个​​和一个实例,这样以后我可以通过名称找到它并使用反射调用它。

我认为Delegate可以,但我找不到将静态或实例方法转换为Delegate. 我还可以创建自己的类或结构来保存一个对象和一个MethodInfo,但如果是这样,我的类的用户将不得不MethodInfo放弃他想要添加到我的字典中的任何方法,并且需要添加对Reflection任何地方的引用(而不是仅仅传递方法本身或类似的东西(Delegate)myMethod)。有没有办法做到这一点?

4

3 回答 3

2

听起来您只想拥有一个Dictionary<string, Action>可以与 lambda 函数连接的函数:

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

actions.Add("Foo", () => Console.WriteLine("Bar!"));

Car myCar = new Car();
actions.Add("Vroom", () => myCar.Drive());

actions["Foo"](); //prints "Bar!"
actions["Vroom"](); //invokes myCar.Drive

这样,所有不同的签名、对象引用、静态方法或任何由 lambda 及其闭包语义处理的东西。

如果您希望能够将一些上下文或输入传递给集合,您可以提供一个无类型的context对象,您可以在注册方法时对其进行转换。代替无参数Action,您将拥有一个Action<object>

var actions = new Dictionary<string, Action<object>>();

var JuanLuisSoldi = new Person();
actions.Add("Lunch Time", context => JuanLuisSoldi.Eat((Food)context));

Food lunch = new Apple();
actions["Lunch Time"](lunch);
于 2013-07-15T21:54:06.390 回答
2

如果您不介意每次添加到字典时都指定委托类型,那么您可以使用Delegate

void A() {}
string B(string arg) { return arg; }

void Test()
{
    var dict = new Dictionary<string, Delegate>();

    dict.Add("A", new Action(A));
    dict.Add("B", new Func<string, string>(B));
}
于 2013-07-15T21:58:05.443 回答
1

有很多方法,这是一种方法:

public class SomeClass
{
    public IDictionary<string, Action> ActionRegistry { get; set; }

    public void SomeMethod()
    {
        // Registering an action that doesn't use reflection:
        ActionRegistry.Add("SomeAction", () => { Console.WriteLine("Hello");});

        // Registering an action that uses reflection
        object objectInstance; = ...
        Type type; = ...
        string methodName; = ...
        object[] arguments; = 
        ActionRegistry.Add("SomeAction2", () =>
        {
            type.GetMethod(methodName).Invoke(objectInstance, arguments);
        });

        // Invoking:
        ActionRegistry["SomeAction2"]();
    }
}

您可以将 lambda/Action 视为适配器。当我反思时,我经常使用类似的词典。

于 2013-07-15T21:54:57.607 回答