Reputation: 95
Suppose I have a generic method. What is the difference between calling the method with specifying the type and calling without it.
When does it become mandatory to specify the type?
Write(1);
Write<int>(1);
Write<string>("test");
Write("test");
private static void Write<T>(T param)
{
Console.WriteLine(param);
}
Upvotes: 2
Views: 73
Reputation: 387507
The compiler will attempt to resolve the type argument at compile time. In cases where this is possible, it is done automatically without you have to specify an explicit type. In all other cases, when the compiler is unable to determine the type argument, the compiler will throw an error and you cannot compile your application.
In your example Write(1)
, the argument 1
is of type int
. So the compiler infers that T
must be int
, so the call is equivalent to Write<int>(1)
. Similarly with Write("test")
, "test"
is of type string
, so the compiler will infer that T
is string
.
This generally works on the compile time type of the argument you pass to the function. So if you have a string with a compile time type of object
, T
would be object
:
object arg = "foo";
Write(arg); // arg is object
// this is equivalent to this:
Write<object>(arg);
So although you are passing a string, its compile time type is object
so that’s the only information, the compiler is able to use here.
In addition, you might want to specify the type argument explicitly whenever you want the compiler to use a different type than the compile time argument of what you’re passing to it. In the above example, you could use Write<object>(1)
which would cause the integer 1
to be casted into object
. However, in practice this usually defeats the purpose of generic methods and may have actual consequences even if you don’t need to access the actual parameter’s compile time type. For example, value types would be boxed when passed as object
but generic methods allow you to keep them as value types—remember that a generic method definition (same applies to types) is kind of equivalent to specifying an overload with every other valid generic type argument value (so you usually have an infinite copy of methods).
Of course, the compiler’s type inference also works with multiple arguments:
void Write<T1, T2>(T1 arg1, T2 arg2)
{ … }
Write(1, "foo");
// is equivalent to
Write<int, string>(1, "foo");
However, when the compiler is not able to infer even one type argument, you will have to specify all of them in the call.
Upvotes: 5
Reputation: 4881
There are no difference between
Write<string>("test");
Write("test");
But, there difference, when you specify not exactly type of parameter, but convertible, for example
Write<object>("test");
Write("test");
Just try to print type parameter and will see difference
private static void Write<T>(T param)
{
Console.WriteLine(typeof(T));
Console.WriteLine(param);
}
Upvotes: 1
Reputation: 2407
It's not mandatory in this situation because the parameter param
is the generic (the compiler resolves it like that).
That means it's mandatory whenever the type argument is not supplied as a parameter.
Upvotes: 3
Reputation: 77285
It becomes mandatory to specify the type when the compiler cannot infer it, or when you are not happy with what the compiler infers.
Upvotes: 2