2017-06-21 61 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