2017-06-21 66 views
0

this answer,我寫了LINQ擴展,利用以下delegate內被推斷,所以可在與out變量的函數通過,如int.TryParse類型不能通用委託

public delegate bool TryFunc<TSource, TResult>(TSource source, out TResult result); 

public static IEnumerable<TResult> SelectTry<TSource, TResult>(
    this IEnumerable<TSource> source, TryFunc<TSource, TResult> selector) 
{ 
    foreach (TSource item in source) 
    { 
     TResult result; 
     if (selector(item, out result)) 
     { 
      yield return result; 
     } 
    } 
} 

爲了要使用這個擴展,我必須明確指定,像這樣的<string, int>類型:

"1,2,3,4,s,6".Split(',').SelectTry<string, int>(int.TryParse); // [1,2,3,4,6] 

我想除去<string, int>,類似於我們怎麼能叫.Select(int.Parse)沒有指定<int>,但是當我做,我得到以下錯誤:

The type arguments for method 'LINQExtensions.SelectTry(IEnumerable, LINQExtensions.TryFunc)' cannot be inferred from the usage. Try specifying the type arguments explicitly.


我的問題是,爲什麼不能在類型推斷?我的理解是,編譯器應該在編譯時知道int.TryParse的簽名,並隨後知道TryFuncdelegate的簽名。

+0

是否https://stackoverflow.com/questions/19015283/why-cant-c-sharp-compiler-infer-generic-type-delegate-from-function-signature幫助? – mjwills

回答

2

它不能推斷,因爲只有其中一個參數適合,這就是字符串。第二個參數是out int,不能在通用參數中指定,這就是爲什麼它不能推斷參數的原因。

無需指定參數即可調用SelectTry的唯一方法是聲明您的代理指向int.TryParse,然後將其作爲參數傳入。

我知道這不是你想要的,這是我知道指定參數的唯一途徑。

TryFunc<string, int> foo = int.TryParse; 
var s = "1,2,3,4,s,6".Split(',').SelectTry(foo); 

請記住,爲了傳遞方法作爲委託,參數必須匹配1:1。 int.TryParse匹配TryFunc,但它不匹配SelectTry