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);
在 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);