返回委托的Lambda表达式

6

您好,我正在尝试实现类似于这样的功能:

Method<TObjectType>(m=>m.GetData); //m is the instance of TObjectType

如果我能成功,那么我就可以访问这个表达式并获取GetData方法,然后使用它创建动态SQL查询。我可以通过将方法名称作为字符串来实现这一点,但我不想破坏开发人员朋友的强类型世界。
我知道我必须给出委托的确切定义,但这仍然没有帮助我;
void Method<TObjectType>(Expression<Func<TObjectType, Delegate>> ex){/**/}

你有什么想法吗?


你知道关于 GetData() 的任何信息吗?你知道它是否总是没有参数,或者类似的东西吗? - svick
如果您不知道GetData方法的签名,您将离开强类型世界。 - Emond
这也许对你有帮助 https://dev59.com/K3E85IYBdhLWcg3wUBsZ - Vinoth
@svick 方法的签名应该是泛型的,因为它可以是任何方法。 - Mert Susur
@Erno 我也是这么认为的,恐怕是这样。 - Mert Susur
2个回答

6

很遗憾,"代表"这样的东西几乎不存在。对于大多数目的(特别是:解析MethodInfo),它必须是一个强类型的委托。这是因为GetData不是一个方法,而是一个方法组。你真的需要精确地指定方法,或者拥有已知的委托类型(最终执行相同的操作)。

你有两个实用的选项:将其工作为object,或添加一个泛型。例如:

void Method<TObjectType>(Expression<Func<TObjectType,object>> ex) {...}

可以使用以下方法解决,例如:

void Method<TObjectType, TValue>(Expression<Func<TObjectType,TValue>> ex) {...}

调用者将使用:

Method<Foo>(x => x.GetData());

如果你真的想使用委托(delegate),那么类型必须是可预测的,例如:
void Method<TObjectType>(Expression<Func<TObjectType,Func<int>>> ex)

允许:

Method<Foo>(x => x.GetData);

或者,如果您知道(例如)该方法始终没有参数,但您不知道返回类型;也许是这样的:

void Method<TObjectType, TValue>(Expression<Func<TObjectType,Func<TValue>>> ex)

这使得:

Method<Foo, int>(x => x.GetData);

在这种情况下,我想你假设GetData方法是无参数的,以便您可以使用Func<T>定义它。这意味着,我必须进行大量的方法重载,我是正确的吗? - Mert Susur
@lazycoder 我建议不要这样做,因为你最终会创建一个具有大量泛型类型参数的方法,这样调用起来非常不方便。我实际上建议使用更简单的 object/TValue 方法,调用者可以指定 x.GetData()。对于更复杂的重载,他们总是可以指定 x.GetData(123, "abc", DateTime.Now) - 表达式树将告诉您他们使用了哪个重载以及(如果您需要)参数值。 - Marc Gravell
@lazycode 最坏情况下,你需要两个重载;一个 Func<TObjectType,object>,一个 Action<TObjectType>(用于 void 方法) - Marc Gravell
谢谢,我想我有两种方法;一种方法是强制开发人员定义至少一个无参数覆盖,另一种方法是像Erno所说的那样“离开强类型世界。” :) - Mert Susur

0
你是否在寻找类似这样的东西?
object InvokeMethod(Delegate method, params object[] args){
    return method.DynamicInvoke(args);
}

int Add(int a, int b){
    return a + b;
}

void Test(){
    Console.WriteLine(InvokeMethod(new Func<int, int, int>(Add), 5, 4));
}

谢谢您的回答,但我不想调用这个方法,我只想让开发人员使用强类型定义一些东西。 - Mert Susur

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接