2009-08-15 87 views
134

我可以通過帶有out參數的方法作爲Func嗎?Func <T>不帶參數

public IList<Foo> FindForBar(string bar, out int count) { } 

// somewhere else 
public IList<T> Find(Func<string, int, List<T>> listFunction) { } 

Func鍵需要一個類型,這樣出去不會編譯那裏,並呼籲listFunction需要一個int,不會允許一個徹頭徹尾。

有沒有辦法做到這一點?

回答

192

refout不是類型參數定義的一部分,所以你不能使用內置Func代表通過refout參數。當然,你可以聲明自己的委託,如果你想:

delegate V MyDelegate<T,U,V>(T input, out U output); 
+13

如果有人像我一樣感到困惑,你不會*像*內建的那樣*調用你的委託「Func」... – Dunc 2013-03-27 14:58:56

+0

@Dunc - 修正。如果不是您的評論,我會感到非常困惑。 – 2014-04-12 00:08:27

+5

在C#4(2010)及更高版本(在您寫答案時未發佈),可以將「T」標記爲逆變,將「V」標記爲協變。然而,由於類型'U'的參數('output')通過引用***被***傳遞,所以'U'不能被標記爲共同或逆變,並且必須保持「不變」。所以考慮在T,U,out V>(T輸入,U輸出)中的公共代理V MyDelegate <如果使用C#4或更高版本。 – 2014-04-22 10:04:28

19

爲什麼不創建一個類來封裝結果?

public class Result 
{ 
    public IList<Foo> List { get; set; } 
    public Int32 Count { get; set; } 
} 
0

你可以將它包裝在一個lambda /代表/功能/方法右暴露接口,並呼籲FindForBar,但我懷疑FindForBar已經算爲理由out參數,所以你需要一定要把這些信息扔掉是好的/安全的/理想的/有正確的結果(即使你可以直接通過FindForBar,你也需要確保這一點)。

9

Func家族的代表(或Action爲此事)是什麼,但聲明如下

//.NET 4 and above 
public delegate TResult Func<out TResult>() 
public delegate TResult Func<in T, out TResult>(T obj) 

//.NET 3.5 
public delegate TResult Func<T1, T2, TResult>(T1 obj1, T2 obj2) 
public delegate TResult Func<T1, T2, T3, TResult>(T1 obj1, T2 obj2, T3 obj3) 

等代表簡單的委託類型因爲這樣可以有out/ref參數,所以在你的情況下,只有你自己定製實現的問題,正如其他答案指出的那樣。至於爲什麼微軟沒有默認包裝這個,想想它需要的組合數量。

delegate TResult Func<T1, T2, TResult>(T1 obj1, T2 obj2) 
delegate TResult Func<T1, T2, TResult>(out T1 obj1, T2 obj2) 
delegate TResult Func<T1, T2, TResult>(T1 obj1, out T2 obj2) 
delegate TResult Func<T1, T2, TResult>(out T1 obj1, out T2 obj2) 

只有兩個參數。我們甚至沒有碰過ref。這對於開發者來說實際上會很麻煩和混亂。

+1

請注意,C#函數重載無法區分'delegate TResult Func (T1 obj,T2 obj)'和'委託TResult Func (out T1 obj,T2 obj)'。因此,除了重載次數之外,符號名稱是Microsoft爲什麼不能添加這些「Func」重載的另一個原因。 – 2016-10-10 14:04:59