Разница между реализацией var в Javascript и C # - PullRequest
30 голосов
/ 10 декабря 2011

Я хотел бы задать теоретический вопрос.Если у меня есть, например, следующий код C # в Page_load:

cars = new carsModel.carsEntities();

var mftQuery = from mft in cars.Manufacturers 
               where mft.StockHeaders.Any(sh=> sh.StockCount>0) 
               orderby mft.CompanyName 
               select new {mft.CompanyID, mft.CompanyName};
               // ...

Вопросы:

  1. В этом коде используется ключевое слово var.В чем выгода этой конструкции?
  2. В чем ключевое отличие реализации var в Javascript и C #?

Ответы [ 5 ]

78 голосов
/ 10 декабря 2011

JavaScript - это язык с динамической типизацией, в то время как c # - это (обычно) язык со статической типизацией. В результате, подобные сравнения всегда будут проблематичными. Но:

Ключевое слово JavaScript var несколько похоже на ключевое слово C # dynamic. Оба создают переменную, тип которой не будет известен до времени выполнения, а злоупотребление не будет обнаружено до времени выполнения. Именно так JavaScript всегда , но это совершенно новое для C # 4.

dynamic foo = new DateTime();
foo.bar();  //compiles fine but blows up at runtime.

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

Для примера первого:

var conn = new System.Data.SqlClient.SqlConnection("....");

Хороший пример второго - проекции анонимного типа из Linq-to-Sql или Entity Framework:

var results = context.People.Where(p => p.Name == "Adam")
                            .Select(p => new { p.Name, p.Address });

Здесь results относится к типу IQueryable<SomeTypeTheCompilerCreatedOnTheFly>. Независимо от того, сколько вы хотели бы выписать фактический тип результатов, вместо того, чтобы просто писать var, это невозможно, так как вы не знаете тип, который компилятор создает под прикрытием для вашего анонимного типа - следовательно, терминология: этот тип является анонимным

В обоих случаях тип известен в время компиляции , и в обоих случаях впоследствии говорится либо

conn = new DateTime();

или

results = new DateTime();

приведет к ошибке компилятора , так как вы устанавливаете conn и results для типа, который не совместим с тем, что они были объявлены как .

10 голосов
/ 10 декабря 2011

a) C # var позволяет избежать написания явного типа при объявлении переменной.Это делает ваш код более компактным, и иногда тип выражения в правой части объявления усложняется, и в то же время вы не интересуетесь фактическим типом.

b) Javascript var похож на C # dynamic.Он позволяет вам объявить переменную, но вы можете изменить ее тип.

var i = 1; 
i = "foo";  // legal in Javascript, illegal in C#
7 голосов
/ 10 декабря 2011

Единственное, что у них общего, - это то, что они используются для объявления локальных переменных.

С # эквивалент JS var равен dynamic. Но поскольку большинство пользователей C # предпочитают статическую типизацию, она обычно используется только в некоторых сценариях взаимодействия (с COM или динамически типизированным языком).

C # var все еще использует статическую типизацию, но с предполагаемым типом. Поскольку JS поддерживает только динамическую типизацию, эквивалент не существует.

В этом контексте явная статическая типизация невозможна, поскольку new {mft.CompanyID, mft.CompanyName} создает анонимный тип , поэтому используется неявная статическая типизация с var.

1 голос
/ 10 декабря 2011

var в C # является динамическим во время разработки, но статически типизируется во время компиляции. Вы увидите, что если вы сделаете:

var mftQuery = from mft in cars.Manufacturers
    where mft.StockHeaders.Any(sh=> sh.StockCount>0) 
    orderby mft.CompanyName
    select new {mft.CompanyID, mft.CompanyName};

и затем:

mftQuery = "Hello world!";

Он не скомпилирует и не будет жаловаться на несовпадение типов, даже если вы не указали какой-либо тип.

Это полезное повышение производительности, поскольку вы можете легко изменять типы возвращаемых данных на аналогичные, не нарушая ничего, и их легче писать. Глупый пример:

foreach(var animal in GetCats()){
   Console.WriteLine(animal.Owner);
}

можно изменить на:

foreach(var animal in GetDogs()){
   Console.WriteLine(animal.Owner);
}
0 голосов
/ 11 декабря 2011

И чтобы ответить на ваш вопрос 1 , преимущество использования ключевого слова var в представленном коде может быть затруднительным для определения результирующего типа для запроса LINQ и может быть легко затронутоизменение в запросе.Фактически, его введение в C # совпадает с премьерой LINQ.

Предполагается, что это облегчает жизнь программиста, а также устраняет избыточность Type t = new Type().

...