ro_
ro_

Reputation: 1

Type arguments for a method reference can't be inferred from the usage

I'm getting this error in C# on .NET 8.0 (and .NET 6.0 if I'm being pedantic):

Error CS0411: The type arguments for method 'Foo.Execute<I, O>(Func<I, O>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

On this line:

Execute(Method);

In this snippet:

public class Foo
{
    public class Baz { }
    public class Bat { }

    public void Bar()
    {
        Execute((Baz baz) =>
        {
            return new Bat();
        });

        Execute(Method);
    }

    public Bat Method(Baz baz)
    {
        return new Bat();
    }

    public void Execute<I, O>(Func<I, O> func)
    {
    }
}

Is there any way I can go about adjusting my setup here so I don't have to explicitly include Baz into the line of code in question here?

I know I can do:

Execute((Baz baz) => Method(baz));

But that kinda rubs me the wrong way. I'm trying to avoid having to specify types in more than just the method's location, and as far as I'm concerned that Baz in the lambda is still explicitly typing it.

Thanks for any help :)

Upvotes: 0

Views: 142

Answers (2)

wohlstad
wohlstad

Reputation: 28084

In this line:

Execute(Method);

The compiler cannot infer the generic types for Execute, because Method is not a Func<I, O> (although it can be converted to one).

To solve it, as suggested by the compiler ("Try specifying the type arguments explicitly."), you can explicitly specify the generic types for Execute in the following way:

//------vvvvvvvv----------
Execute<Baz, Bat>(Method);

A side note:
In order to actually do something in Execute with Func<I,O> func (i.e. call it), you need to also pass the relevant I parameter to call it with.

Upvotes: 0

Felix
Felix

Reputation: 10078

Your Execute() function takes a function variable. Method is not a variable. You need to create a variable like

private readonly Func<Baz, Bat> fnMethod = (baz) => Method(baz);

then you can invoke

Execute(fnMethod);

And yes, your anonymous function does pretty much the same. My code simply spells it out. The benefit is that if you have numerous invocations, you specify type in two places

If you really want to specify only once, I suppose you can do this:

private readonly Func<Baz, Bat> fnMethod = baz => new Bat();

and you don't need Method() at all. In real world you will likely have the body of the function instead of simply new Bat() - but I think you got the point

Upvotes: 0

Related Questions