为什么编译器不允许我们使用`var`而不是`generic type`?

时间:2018-05-17 13:36:07

标签: c# generics var generic-type-argument

在下面的示例代码中,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 typevar之间的区别吗?

1 个答案:

答案 0 :(得分:4)

它不编译,所以它不起作用。

泛型和var的使用非常不同。 var意思是“编译器,我很懒,请为我发现我应该在这里使用的单一确切类型,从我写的= =”之后推断它(在某些情况下,它必须是使用var而不是明确写出变量类型,但我们会忽略它们... ...例如

var foo = "Hello";

foo变量类型为string,因为编译器可以通过查看赋值=之后的表达式类型来推断它。 var完全被编译程序中的“正确”类型所取代。

所以它等同于写作:

string foo = "Hello";

泛型是一种使方法/类能够适应调用/创建它们的不同类型的方法。在这种情况下,调用者可以

int[] foo1 = Reverse(new int[] { 1, 2, 3, 4, 5);

long[] bar1 = Reverse(new long[] { 1, 2, 3, 4, 5);

编译器(因为泛型在编译时被解析)将从所使用的参数推断类型Tintlong)并将其写入某处(在编译的文件中) )。然后运行时将看到这个并创建两个不同的Reverse专用版本(一个用于int,另一个用于long)。但在这种情况下,T是对各种可能类型的参数的“开放性”。在var的情况下,变量可以是一种可能的类型。所以在编译文件中有一个Reverse<T>编译方法,而在运行时有方法的Reverse<int>版本和方法的Reverse<long>版本(如果需要,运行时将创建该方法的其他版本)。

使用var作为参数没有任何意义,并且它将比泛型的语法更差,其中使用的泛型列表放在某处(在方法名称和{{1之间)在这种情况下)你可以有多个泛型类型,比如

(

(即LINQ public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector) ),其中有两个通用参数SelectTSource。使用您的语法,您将无法区分两个通用参数(只有一个TResult关键字),并且您无法使用当前使用的var(编译器,我是懒,请发现这个局部变量的类型。)