參數被定義,只是它們的類型被推斷出來。參數定義是=>
- list
(推斷爲IList<T>
類型)和x
(推斷爲float
類型)之前的部分,分別在您的示例中。
首先代表對應的簽名:
T SomeMethod<T>(IList<T> list)
二是:
float SomeMethod(float x)
由於編譯器知道委託的簽名必須是什麼,它可以推斷出所需要的類型自動。如果你是使用舊的學校明確語法寫出來的代表,它會是這個樣子:
return (Func<IList<T>, T>)(delegate (IList<T> list) { return list.First(); });
如果你真的想使用顯式類型,您可以指定類型的需要:
(IList<T> list) => list.First()
當你真正要調用的委託,你需要傳遞參數,如:
SelectionMethod<string>()(new List<string>())
第一個lambda表達式是非常簡單的。第二種方法還關閉了「creator」函數的參數,這意味着您可以訪問委託主體中「creator」的參數。這在純粹不可變的代碼中是完全安全的,但是如果你處理可變引用類型和副作用可能會很棘手 - 確保你在對這些引用做任何事情之前正確理解語義。
根據您在函數式編程方面的經驗,瞭解所有這些只是編譯器的詭計可能會有幫助。這兩種方法將編譯到的東西相當於這樣的:
public Func<IList<T>, T> SelectionMethod<T>()
{
return new Func<IList<T>, T>(__HiddenAnonymousMethod);
}
private T __HiddenAnonymousMethod<T>(IList<T> list)
{
return list.First();
}
第二個例子是比較複雜的,因爲封閉的 - 我們需要創建一個「輔助對象」來保存捕獲當地人:
private class __HiddenAnonymousClass
{
float a, b, c;
public __HiddenAnonymousClass(float a, float b, float c)
{
this.a = a; this.b = b; this.c = c;
}
public float __HiddenAnonymousMethod(float x)
{
return a * x * x + b * x + c;
}
}
public Func<float, float> QuadraticFunctionMaker(float a , float b , float c)
{
return new Func<float, float>
(new __HiddenAnonymousClass(a, b, c).__HiddenAnonymousMethod);
}
很好的解釋。我確實發現所有這些新的語法越來越模糊,我傾向於避免在我的代碼中使用任何語法快捷方式,我覺得它們使代碼更不易讀。 – Stefano