2012-12-03 103 views
1

假設我有這樣的功能:C#委託和函數調用

Func<string> fs =() => "test"; 
var st = fs(); 

我想簡化這:

var st = (()=> "test")(); 

看來不過,我不能定義函數,然後立即調用它。這可能以另一種方式嗎?

這是可能的:

var st = (new Func<string>(() => "test"))(); 

但是很凌亂。

爲了闡明它是可能的,而不需要指定所使用的委託類型來定義一個匿名函數,即是有辦法讓編譯器直接從函數推斷類型?

+2

你爲什麼要這麼做? – Henrik

+0

這是什麼問題? – leppie

+0

,我想暫時範圍在函數調用 –

回答

4

你需要以某種方式指定類型。其他人已經展示瞭如何在線實現這一點。

還有另一種可能性:創建一個輔助方法。由於方法的參數已定義,因此在調用方法時無需自己定義類型。

static class Execute 
{ 
    public static T Func<T>(Func<T> func) 
    { 
     return func(); 
    } 
} 

用法:

var st = Execute.Func(() => "test"); 
+0

一些變量,我喜歡這一點,因爲它具有較小的弧形托架這將成爲用於包裝更復雜的功能非常有用。你知道編譯器是否最終能夠在沒有類型減速的情況下支持函數? –

+0

@MichaelEdwards:我不知道編譯器會支持什麼。我可以想象它可能會實現這一點 - afaik F#已經有這個 - 但這並不意味着它實際上會在某個時刻實現。順便說一句:調用'Func'時不需要泛型類型參數(請參閱更新的用法)。 –

3

只投的表達,正確的類型是這樣的:

var st = ((Func<string>) (() => "test"))(); 
1

基本上編譯器不知道它是否是一個表達式樹或匿名方法。你想要後者,你必須在路上指定一個類型。

如果你不想投的拉姆達在線,你應該輔助方法去:

static TResult call<TResult>(Func<TResult> f) 
{ 
    return f(); 
} 
static TResult call<T1, TResult>(Func<T1,TResult> f, T1 arg1) 
{ 
    return f(arg1); 
} 
static TResult call<T1, T2, TResult>(Func<T1, T2, TResult> f, T1 arg1, T2 arg2) 
{ 
    return f(arg1, arg2); 
} 
// and so on... 

static void Main(string[] args) 
{ 
    Console.WriteLine(call(() => "test")); 
}