Well, generic type inference requires that method arguments provide the type for the arguments to let the compiler infer their generic types.
So only TArg
could be infered, while TResult
not. In summary: no, you can't call a generic method without providing all generic arguments.
Possible alternative: refactor your code as follows...
I believe that I can give you a draft of what I would consider a better design in your case. Check the code and later I explain it bellow the sample:
public interface ICommand<TArg, TResult>
{
TArg Arg { get; set; }
TResult Run();
}
public sealed class ConvertCommand : ICommand<string, double>
{
public string Arg { get; set; }
public double Run()
{
return Convert.ToDouble(Arg);
}
}
public static class CommandFactory
{
public static TCommand Create<TCommand, TArg, TReturnValue>(TArg arg)
where TCommand : ICommand<TArg, TReturnValue>, new ()
{
var cmd = new TCommand();
cmd.Arg = arg;
return cmd;
}
// This is like a shortcut method/helper to avoid providing
// generic parameters that can't be inferred...
public static ConvertCommand ConvertCommand(string arg)
{
return Create<ConvertCommand, string, double>(arg);
}
}
class Interpreter
{
public TReturnValue Run<TArg, TReturnValue>(ICommand<TArg, TReturnValue> cmd)
{
return cmd.Run();
}
}
I think that you shouldn't delegate the responsibility of building commands to the interpreter, but it should be a command factory. That is, the interpreter just run the command, gets command results, processes them, emits events... this is now up to you.
In the other hand, check that Interpreter.Run
method receives an ICommand<TArg, TReturn>
instead of a generic type parameter. This way, **both TArg
and TReturn
generic type arguments can be inferred from the ICommand<TArg, TReturn>
from its implementation and you don't need to provide these generic arguments explicitly:
Interpreter interpreter = new Interpreter();
// TArg and TReturn are inferred!!
interpreter.Run(CommandFactory.ConvertCommand("0.1"));
Actually I would go with other designs/architectures in a real-world scenario, but I wanted to give you a hint on how to refactor your actual idea and let it work as you expect ;)