In the example code below Generic Type
is used in writing a Reverse function that reverses an array of any type:
public T[] Reverse<T>(T[] array)
{
var result = new T[array.Length];
int j=0;
for(int i=array.Length; i>= 0; i--)
{
result[j] = array[i];
j++;
}
return result;
}
However, I could write the same code like below by using var
type:
public var[] Reverse(var[] array)
{
var result = new var[array.Length];
int j=0;
for(int i=array.Length; i>= 0; i--)
{
result[j] = array[i];
j++;
}
return result;
}
However, the compiler does not accept the latter. I want know to the difference between Generic type
and var
?
It doesn't compile, so it doesn't work.
The use of generics and the var
are very different. var
means "compiler, I'm lazy, please discover for me the single exact type that I should use here, inferring it from what I'm writing after the =" (there are some cases where it is mandatory to use var
instead of writing explicitly the variable type, but we will ignore them) ... So for example
var foo = "Hello";
The foo
variable type is string
, because the compiler can infer it by looking at the type of the expression after the assignment =
. The var
is totally replaced by the "correct" type in the compiled program.
So it would be equivalent to writing:
string foo = "Hello";
Generics instead are a way to make a method/class able to adapt to different types that are used in calling/creating them. In this instance the caller could
int[] foo1 = Reverse(new int[] { 1, 2, 3, 4, 5);
or
long[] bar1 = Reverse(new long[] { 1, 2, 3, 4, 5);
The compiler (because generics are resolved at compile time) will infer the type T
(int
or long
) from the parameters used and will write it somewhere (in the compiled file). The runtime then will see this and create two different specialized versions of Reverse
(one for int
and one for long
). But in this case T
is an "openness" to the various possible types of parameters. In the case of var
, there is a single possible type that the variable can be. So in the compiled file there is a Reverse<T>
compiled method, while at runtime there are a Reverse<int>
version of the method and a Reverse<long>
version of the method (and if necessary the runtime will create other versions of the method).
Using var
as a parameter wouldn't have any meaning, and it would be a poorer syntax than the generics one, where the list of used generics are put somewhere (between the method name and the (
in this case) and you can have multiple generic types, like
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
(that is the LINQ Select
) where there are two generic parameters TSource
and TResult
. With your syntax you wouldn't be able to differentiate between the two generic parameters (there is a single var
keyword), and you couldn't use var
as is currently used (compiler, I'm lazy, please discover for the the type of this local variable).