如何返回委托功能或C#中的lambda表达式?

问题描述:

我想写返回自己的一个实例的方法。 该伪代码是如何返回委托功能或C#中的lambda表达式?

Func<T,Func<T>> MyFunc<T>(T input) 
{ 
    //do some work with input 
    return MyFunc; 
} 

似乎很简单。但是我在定义返回类型时遇到了问题。 返回类型应该是一个代表

which takes T as parameter, then returns a function 
which takes T as parameter, then returns a function 
which takes T as parameter, then returns a function 

    ...recursive definition 

我可以肯定的是,我没有注意到一些微妙的东西。有人可以为我指出吗? 谢谢。

+0

我不知道为什么你要做到这一点 – 2011-04-28 04:54:46

+0

我正在写一个实用的方法,它是静态的内部静态类。我也想要“流利”功能MyFunc(a).MyFunc(b)...但是因为我在一个静态类中。无法返回类本身的一个实例。 – 2011-04-28 04:57:36

你可以这样说:

delegate F<T> F<T>(T obj); 

F<T> MyFunc<T>(T obj) 
{ 
    return MyFunc; 
} 

但它几乎无用。你真的可以做的唯一事情是这样的,这是奇怪的:

void Main() 
{ 
    MyFunc(1)(2)(3)(4); 
} 

delegate F<T> F<T>(T obj); 

F<T> MyFunc<T>(T obj) 
{ 
    Console.WriteLine(obj); 
    return MyFunc; 
} 
+0

不知道为什么我没有想到... +1。 – Justin 2011-04-28 05:08:34

+1

我有错误检查代码块为我正在实施的每个方法。它们都非常相似,如if(a == null)抛出新的NullArgumentException;所以,有ErrorCheck(a)(b)(c)(d);这样我就可以在一行中完成所有的错误检查。代码将不那么混乱。我会立即尝试你的解决方案。如果它有效,它将会非常出色:) – 2011-04-28 05:09:20

+0

它像魅力一样工作。谢谢哥们。 – 2011-04-28 05:16:45

这听起来很像一个迭代器。如果你可以重构你的代码是这样的:

哪里T是你的输入类型和P是你的结果类型。不完全相同,但它应该完成工作。

编辑:相反,如果你想有一个流畅的界面,图案几乎一成不变的:你创建一个非静态类,并从每个函数返回它(这是不是静态的)你打电话。静态类的非静态版本被称为,你可以使用它的这种模式。

+0

我实际上正在尝试使用这个实用方法来执行一些常见的任务来实现LinQ2Object函数,比如Where,Select等等。你编写的代码都很好,但这是“真正”工作的一部分。我的实用方法打算在运行此部分之前进行错误检查。 – 2011-04-28 05:04:58

我不知道你想达到什么目的,但作为一个知识分子演习“我可以返回,返回自己的方法?”以下工作:

object MyFunc<T>(T input) 
{ 
    Func<T, object> returnValue = MyFunc; 
    return returnValue; 
} 

像你说的,你不能有方法返回一个Func,因为这将意味着委托的返回类型将需要一个Func返回一个Func返回一个Func等...

我能看到的这种无限回忆的唯一出路是让它返回一个object来代替,这要求调用者转换为正确的类型。

编辑: Porges答案比较好...

+0

正如我在porges的回复中所写的那样。我正在写错误检查代码,重复了很多。通过这样做,代码非常简洁。 – 2011-04-28 05:20:24

+0

@WeiMa另一种选择可能是使用'params' - 我个人更喜欢明确地处理错误处理。即使它更冗长,它通常会使其更清晰。无论如何,这是一个有趣的问题。 – Justin 2011-04-28 05:22:35

+0

或者如果您使用.NET4来保存必要的投射,则会返回动态。 – Michael 2011-04-28 06:08:56

另一种方式来做到这一点是让组合子。容易松动,但由于无限的倒退,你不能用泛型来做到这一点。你必须直接声明:

delegate D D(D d); 

也就是说,D是一个代表,它接受一个D并返回一个D。

static D MyCombinator(D d) 
{ 
    return MyCombinator; 
} 

组合程序上的一些更多的心思在C#中的位置:

http://blogs.msdn.com/b/ericlippert/archive/2006/06/23/standard-generic-delegate-types-part-two.aspx