Почему компилятор не позволяет нам использовать `var` вместо` generic type`? - PullRequest
0 голосов
/ 17 мая 2018

В приведенном ниже примере кода Generic Type используется при написании функции Reverse, которая инвертирует массив любого типа:

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?

1 Ответ

0 голосов
/ 17 мая 2018

Не компилируется, поэтому не работает.

Использование дженериков и 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);

Компилятор (поскольку обобщенные типы разрешаются во время компиляции) выведет тип T (int или * 1026).*) из используемых параметров и напишу его где-нибудь (в скомпилированном файле).Затем среда выполнения увидит это и создаст две разные специализированные версии Reverse (одну для int и одну для long).Но в этом случае T - это «открытость» для различных возможных типов параметров.В случае var существует единственный возможный тип, которым может быть переменная.Таким образом, в скомпилированном файле есть скомпилированный метод Reverse<T>, в то время как во время выполнения есть версия метода Reverse<int> и версия метода Reverse<long> (и при необходимости среда выполнения создаст другие версии метода).

Использование var в качестве параметра не имело бы никакого значения, и это был бы более слабый синтаксис, чем синтаксис обобщений, где список использованных обобщений помещен где-то (между именем метода и ( в этом случае), и вы можете иметь несколько универсальных типов, например

public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)

(то есть LINQ Select), где есть два универсальных параметра TSource и TResult.С вашим синтаксисом вы не сможете различить два общих параметра (есть одно ключевое слово var), и вы не можете использовать var, как используется в настоящее время (компилятор, я ленивый, пожалуйста, узнайтедля типа этой локальной переменной).

...