C#成员方法作为静态方法("反向扩展方法")

时间:2016-09-07 07:23:57

标签: c# lambda delegates function-pointers extension-methods

是否可以在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;

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

// 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?

3 个答案:

答案 0 :(得分:7)

如果你的意思是&#34;你能创建一个这样的代表吗?#34;然后答案是&#34;是的,但它有点丑陋&#34;。我不会认为您可以使用方法组转换,但您可以使用反射和Delegate.CreateDelegate,例如。

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

在这里进行方法组转换会很高兴,我同意。

答案 1 :(得分:2)

这可能对您的用例不起作用,但您可以使用

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

并使用它

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

答案 2 :(得分:1)

如果您不想每次都进行评估,也许您可​​以进行评估Lazy

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