2010-08-17 55 views
0

好了,在Python可以做到这一点:奇怪的想法:C# - 声明的方法insinde另一种方法

def foo(monkeys): 
    def bar(monkey): 
     #process and return new monkey 
    processed_monkeys = list() 
    for monkey in monkeys: 
     processed_monkeys += bar(monkey) 
    return processed_monkeys 

(这只是个愚蠢的例子) 有时候我会想念声明内的另一个方法的这种功能方法在C#中。但今天我对完成这个如下想法:

List<Monkey> foo(List<Monkey> monkeys) 
{ 
    Func<Monkey, Monkey> bar = delegate(Monkey monkey) 
    { 
     //process and return new monkey 
    } 
    List<Monkey> processed_monkeys = new List<Monkey>(monkeys.Count); 
    foreach(Monkey monkey in monkeys) 
     processed_monkeys.Append(bar(monkey)); 
    return processed_monkeys; 
} 

显然,解决方法不提供完全相同的功能与原来的Func键或操作委托仅限于4个参数,但超过4个参数很少需要...

你对此有什么看法?
这是邪恶的,应该避免所有,但非常特殊的情况?
这是怎么回事?每次函数被调用时,是否会创建一个新的bar函数,或者编译器会以某种方式优化它?

+1

其实,Func <...>只限于16个参数(.Net 4.0),应该足够了;-) – 2010-08-17 12:42:32

+0

好的,我仍然在.Net 3.0上。 我想知道有没有人遇到过他想要传递超过16个参数的情况......故事,任何人? ;-) – licensedlice 2010-08-17 12:46:27

+0

我在.NEt 2.5中有一个函数,它有更多的功能。但是,在我谈论的情况下,我相信这是完全可以接受的:) – 2010-08-17 12:52:25

回答

5

...作为Func键或 行动代表仅限于4个 参数...

与.NET 4.0开始,这些委托类型最多是17的参数定义。您还可以很简单地为任意数量的参数定义自己的参数;例如,下面我定义了一个委托,它需要5个参数:

public delegate void Action<T1, T2, T3, T4, T5>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); 

你如何看待这个观点?

这完全没问题。不管你信不信,.NET开发人员总是这样做。

这是邪恶的,应该避免 所有,但非常特殊的情况?

不,它是非常良性的。它确实没有任何伤害。

这是怎么回事?每次调用 函数时,是否会创建一个 新的bar函数,或者 编译器会以某种方式优化它?

表现很不错。编译器将定义一个实际的成熟CLR类型来提供匿名方法,就像它为匿名类型和使用yield关键字的方法定义成熟的CLR类型一样。别担心,匿名方法不会在每次调用时产生动态编译!真的,如果你考虑一下,那将是非常荒谬的。

这甚至不是我所谓的“优化”;这只是匿名方法由编译器实现的方式。

+2

“编译器将定义一个实际的方法”。它实际上生成一个类来包装该方法。 – 2010-08-17 12:52:08

+0

@理查德:谢谢 - 更新了答案以反映这一事实。 – 2010-08-17 13:02:55

2

您可以使用lambda表达式语法,因此代码会稍微短一点,您不会被限制为4个参数。

var bar = (monkey) => { return new Monkey(); } 

Imho,它不是邪恶的。委托将被明确编译一次,所以委托和静态方法之间的性能差异不会很大。

当然,就像往常一样,这种技术不应被过度使用,以避免产生不可读/不可伤害的代码。

2

它使你的代码难以阅读变得很邪恶,当它更容易阅读时很好,否则就是中性。

+1

不管什么时候改变都不好,就让它独自一人。 – 2010-08-17 14:07:03

0

在学习Scheme之后,我在C#中使用了这种'模式'。

创建可捕获可用作继续函数的值的闭包非常方便(尤其是在异步使用时)。

0

只有当特定的子功能只用于这个功能时,我认为它很好。否则,你将不得不重复它,这对我来说是邪恶的。