C# 成员方法作为静态方法 ("reversed extension method")

C# member method as static method ("reversed extension method")

在 C# 中是否可以在不指定对象的情况下获取对成员函数的引用,以便它可以像静态扩展方法一样使用,将对象作为第一个参数?

class Handler
{
    public void Add(int value) { ... }
}

static class HandlerExtensions
{
    public static void AddEx(this Handler instance, int value) { ... }
}


var x = new Handler();

// possible:
Action<int> func1 = x.Add;
Action<Handler, int> func2 = HandlerExtensions.AddEx;

// not possible?
Action<Handler, int> func3 = Handler::Add;

我为什么要这样做?在使用实际对象之前指定要在 class 中调用的方法:

// current solution:
void RegisterDto<DataType>(Func<Handler, Action<DataType>> handler) { ... }
RegisterDto<int>(x => x.Add);

// desired solution:
void RegisterDto<DataType>(Action<Handler, DataType> handler) { ... }
RegisterDto<int>(Handler::Add); // <--- does syntax for this exist?

如果你的意思是 "can you create a delegate like that" 那么答案是 "yes, but it's slightly ugly"。我不认为你可以使用方法组转换,但你可以使用反射和Delegate.CreateDelegate,例如

MethodInfo method = typeof(Handler).GetMethod("Add");
var action = (Action<Handler, int>) 
    Delegate.CreateDelegate(typeof(Action<Handler, int>), method);

如果能在这里进行方法组转换就好了,我同意。

这可能不适用于您的用例,但您可以使用

创建委托
Action<Handler, int> f = (h, v) => h.Add(v);

并使用它

var handler = new Handler();
f(handler, 100);

如果你不想每次都评价,也许你可以Lazy

        Func<Lazy<Handler>, Action<int>> addMethod = target =>  target.Value.Add;
        // example of usage
        var lazyHandler = new Lazy<Handler>();
        Test(addMethod(lazyHandler), 1);