When passing formal arguments to a generic method, relevant generic type arguments can usually be inferred implicitly. If all generic type can be inferred, then specifying them in the syntax is optional.
Consider the following generic method. It has one formal parameter and one generic type parameter. There is a very obvious relationship between them -- the type passed as an argument to the generic type parameter must be the same as the compile-time type of the argument passed to the formal parameter.
void M<T>(T obj)
{
}
These two calls are equivalent:
M<object>(new object());
M(new object());
These two calls are also equivalent:
M<string>("");
M("");
And so are these three calls:
M<object>("");
M((object) "");
M("" as object);
Notice that if at least one type argument cannot be inferred, then all of them have to be specified.
Consider the following generic method. The first generic type argument is the same as the type of the formal argument. But there is no such relationship for the second generic type argument. Therefore, the compiler has no way of inferring the second generic type argument in any call to this method.
void X<T1, T2>(T1 obj)
{
}
This doesn't work anymore:
X("");
This doesn't work either, because the compiler isn't sure if we are specifying the first or the second generic parameter (both would be valid as object
):
X<object>("");
We are required to type out both of them, like this:
X<string, object>("");