为什么编译器不允许我们使用 `var` 而不是 `generic type`?
Why compiler does not allow us to use `var` instead of `generic type`?
在下面的示例代码中,Generic 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;
}
但是,我可以使用 var
类型编写如下相同的代码:
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;
}
但是,编译器不接受后者。我想知道 Generic type
和 var
之间的区别?
它不编译,所以它不起作用。
泛型的使用和var
有很大的不同。 var
表示 "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 =" (有些情况下必须使用 var
而不是显式写变量类型,但我们会忽略它们)...所以例如
var foo = "Hello";
foo
变量类型为string
,因为编译器可以通过查看赋值后表达式的类型来推断=
。 var
在编译程序中完全被 "correct" 类型取代。
所以这相当于写:
string foo = "Hello";
泛型是一种使 method/class 能够适应 calling/creating 中使用的不同类型的方法。在这种情况下,调用者可以
int[] foo1 = Reverse(new int[] { 1, 2, 3, 4, 5);
或
long[] bar1 = Reverse(new long[] { 1, 2, 3, 4, 5);
编译器(因为泛型是在编译时解析的)将从使用的参数推断类型 T
(int
或 long
)并将其写入某处(在编译文件)。然后运行时将看到这一点并创建两个不同的 Reverse
专用版本(一个用于 int
,一个用于 long
)。但在这种情况下,T
是对各种可能的参数类型的 "openness"。在 var
的情况下,变量可能只有一种类型。所以在编译文件中有一个 Reverse<T>
编译方法,而在运行时有一个 Reverse<int>
版本的方法和一个 Reverse<long>
版本的方法(如果需要,运行时将创建该方法的其他版本)。
使用 var
作为参数没有任何意义,而且它的语法比泛型语法更差,泛型的语法被使用泛型列表放在某处(在方法名称和 [ 之间) =34=] 在这种情况下),你可以有多个通用类型,比如
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
(即 LINQ Select
),其中有两个泛型参数 TSource
和 TResult
。使用您的语法,您将无法区分两个通用参数(只有一个 var
关键字),并且您不能像当前使用的那样使用 var
(编译器,我偷懒,请发现这个局部变量的类型)。
在下面的示例代码中,Generic 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;
}
但是,我可以使用 var
类型编写如下相同的代码:
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;
}
但是,编译器不接受后者。我想知道 Generic type
和 var
之间的区别?
它不编译,所以它不起作用。
泛型的使用和var
有很大的不同。 var
表示 "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 =" (有些情况下必须使用 var
而不是显式写变量类型,但我们会忽略它们)...所以例如
var foo = "Hello";
foo
变量类型为string
,因为编译器可以通过查看赋值后表达式的类型来推断=
。 var
在编译程序中完全被 "correct" 类型取代。
所以这相当于写:
string foo = "Hello";
泛型是一种使 method/class 能够适应 calling/creating 中使用的不同类型的方法。在这种情况下,调用者可以
int[] foo1 = Reverse(new int[] { 1, 2, 3, 4, 5);
或
long[] bar1 = Reverse(new long[] { 1, 2, 3, 4, 5);
编译器(因为泛型是在编译时解析的)将从使用的参数推断类型 T
(int
或 long
)并将其写入某处(在编译文件)。然后运行时将看到这一点并创建两个不同的 Reverse
专用版本(一个用于 int
,一个用于 long
)。但在这种情况下,T
是对各种可能的参数类型的 "openness"。在 var
的情况下,变量可能只有一种类型。所以在编译文件中有一个 Reverse<T>
编译方法,而在运行时有一个 Reverse<int>
版本的方法和一个 Reverse<long>
版本的方法(如果需要,运行时将创建该方法的其他版本)。
使用 var
作为参数没有任何意义,而且它的语法比泛型语法更差,泛型的语法被使用泛型列表放在某处(在方法名称和 [ 之间) =34=] 在这种情况下),你可以有多个通用类型,比如
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
(即 LINQ Select
),其中有两个泛型参数 TSource
和 TResult
。使用您的语法,您将无法区分两个通用参数(只有一个 var
关键字),并且您不能像当前使用的那样使用 var
(编译器,我偷懒,请发现这个局部变量的类型)。