2010-08-17 56 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

只有當特定的子功能只用於這個功能時,我認爲它很好。否則,你將不得不重複它,這對我來說是邪惡的。