Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type cannot be inferred within a generic delegate

Tags:

c#

linq

delegates

In this answer, I wrote a LINQ extension that utilizes the following delegate, so I can pass in a function with an out variable, such as 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;
        }
    }
}

In order to use this extension, I have to explicitly specify the <string, int> types like so:

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

I want to remove <string, int>, similar to how we can call .Select(int.Parse) without specifying <int>, but when I do, I get the following error:

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


My question is, why can't the types be inferred? My understanding is that the compiler should know the signatures of int.TryParse and subsequently the TryFunc delegate at compile time.

like image 416
budi Avatar asked Nov 25 '25 07:11

budi


1 Answers

It can't be inferred because only one of those arguments fits and that's the string. The 2nd parameter is the out int and that cannot be specified in the generic arguments which is why it is saying the arguments cannot be inferred.

The only way to call SelectTry without specifying arguments is by declaring your delegate somewhere that points to int.TryParse and then passing it in as your parameter.

I know this isn't what you want, this is the only way I know of getting around specifying the arguments.

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

Remember, in order to pass in methods as delegates, the parameters must match 1:1. int.TryParse matches TryFunc, but it does not match SelectTry

like image 111
TyCobb Avatar answered Nov 26 '25 21:11

TyCobb



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!