var в классе дает ошибку


person Pratik    schedule 21.12.2010    source источник
comment
В функции / методе я могу объявить переменную типа var, тогда почему я не могу сделать это в классе?   -  person Pratik    schedule 21.12.2010
comment
В этом нет необходимости; если бы вы могли это сделать, это просто сделало бы тип переменной менее явным, следовательно, ваш код более неясным. Возможно, вы неправильно понимаете цель ключевого слова var.   -  person Kirk Broadhurst    schedule 21.12.2010
comment
Излишнее раздражающее дублирование при объявлении членов класса: Dictionary ‹string, double› D = new Dictionary ‹string, double› ();   -  person kaalus    schedule 26.03.2020


Ответы (8)


// method variable
var X;

никогда не действителен - даже внутри метода; вам нужна немедленная инициализация, чтобы определить тип:

// method variable
var X = "abc"; // now a string

Что касается того, почему это недоступно для полей с инициализатором поля: просто так сказано в спецификации. Теперь, почему в спецификации говорится, что это еще одна дискуссия ... Я мог бы проверить аннотированная спецификация, но я подозреваю, что они просто более необходимы для переменных метода, где логика более сложная (re LINQ и т. д.). Кроме того, они часто используются с анонимными типами (что является необходимостью для их существования); но анонимные типы не могут быть представлены в общедоступном API ... так что вы можете запутаться:

private var foo = new { x = 123, y = "abc"}; // valid
public var bar = new { x = 123, y = "abc"}; // invalid

Так что в целом меня устраивает текущая логика.

person Marc Gravell    schedule 21.12.2010

Если вы действительно не знаете, какой тип объекта будет содержать ваша переменная экземпляра, используйте object, а не var. var не означает «я не знаю», это означает «вывести тип за меня» - вот почему его нельзя использовать для членов класса.

person Bradley Smith    schedule 21.12.2010
comment
но когда я набираю функцию / метод, я могу объявить переменную типа var - person Pratik; 21.12.2010
comment
@Rahul Он работает в области видимости метода, потому что переменная живет и умирает внутри блока, поэтому компилятор может легко определить ее тип. В области действия класса компилятор должен учитывать состояние, последовательность, экземпляры и всевозможные другие факторы. - person Bradley Smith; 21.12.2010
comment
Ну, что ж, спасибо. Можете ли вы предложить мне некоторые различия и сходства в object & var, из которых я могу решить, могу ли я использовать тип объекта в моем коде. - person Pratik; 21.12.2010
comment
@Rahul, см. этот вопрос о var и object. - person Matthew Flaschen; 21.12.2010
comment
Как сказал Марк, это на самом деле не объясняет, почему он не делает этого, когда есть есть инициализатор поля. - person Matthew Flaschen; 21.12.2010

Потому что C # не поддерживает этот уровень вывода типов. Ваш альтернативный вариант - использовать язык, такой как F #, который действительно поддерживает этот уровень вывода типов, или попросить команду C # реализовать эту функцию. Я догадываюсь, с каким из них тебе повезет больше ...

person James Kovacs    schedule 21.12.2010
comment
использование F # для меня не имеет отношения к делу и не требует от команды C #. Жду чего-нибудь отличного от этих двух! - person Pratik; 21.12.2010
comment
На самом деле C # не поддерживает эту функцию. Я не хотел переключать языки, просто эта поддержка возможна (например, F #), и команда C # решила не реализовывать var для чего-либо, кроме локальных переменных. Умолять команду C # было насмешкой. - person James Kovacs; 21.12.2010

var в C # - это неявно типизированная локальная переменная, используемая для вывода типа из RHS данного выражения, которое необходимо разрешить во время компиляции. Когда вы объявляете var без значения RHS в определении класса, компилятор не может узнать тип, который вы пытаетесь присвоить var.

C # не поддерживает неявную типизацию для переменных класса.

person jatin    schedule 21.12.2010
comment
var X = что-то; // все еще выдает ошибку. - person Pratik; 21.12.2010
comment
var не допускается в рамках класса, точка. - person Matthew Flaschen; 21.12.2010

Поскольку фактический тип переменной выводится из контекста, в котором она используется. Для полей (переменных-членов класса) такого контекста нет.

person gstercken    schedule 21.12.2010
comment
Хотя там может быть через инициализатор поля - person Marc Gravell; 21.12.2010

Вы можете возразить, что намерение совершенно очевидно, если вы напишете var _users = new List<User>() в качестве объявления поля.

Проблема в том, что не все объявления полей содержат присвоение, необходимое для определения типа. (Возможно, вы захотите инициализировать поле через конструктор)

Смешивание объявлений var и нормального типа выглядело бы как неприятный суп. Следовательно, это невозможно.

(по крайней мере, это мое предположение)

person jgauffin    schedule 21.12.2010

Да, ключевое слово var разрешено только для локальных переменных.

Он был введен в язык, чтобы иметь возможность обрабатывать анонимный тип, который существует только в локальной области. Поскольку анонимный тип ограничен локальной областью, имеет смысл разрешить ключевое слово var только в локальной области.

Кроме того, никогда не срабатывает использование ключевого слова var без указания значения, поскольку оно используется для определения типа данных:

var x = "asdf"; // works

var x; // doesn't work

Обычный способ объявления переменной - использование определенного типа данных. Используйте ключевое слово var, когда вы не можете указать тип данных (например, когда тип анонимный) или когда тип избыточен (например, повторяется буквально в значении). Пример:

var x = new { Key = 42, Name = "asdf" };

var y = new System.Text.StringBuilder();
person Guffa    schedule 21.12.2010
comment
Почему голос против? Если вы не объясните, что вы считаете неправильным, это не улучшит ответ. - person Guffa; 21.12.2010

Это все из-за порядка сборки. Вы можете объявить var только в методах. Компилятор сначала создает все, кроме методов, и поэтому тип объекта будет понятен компилятору, если вы используете его внутри метода. У Джона был отличный ответ на этот счет, но он, похоже, не нашел.

person Pabuc    schedule 21.12.2010