Javascript和C#中var的实现差异

时间:2011-12-10 16:00:48

标签: c# javascript .net linq var

我想问一个理论问题。例如,如果我有Page_load中的以下C#代码:

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. 在Javascript和C#中实现var之间的主要区别是什么?

5 个答案:

答案 0 :(得分:78)

JavaScript是一种动态类型语言,而c#(通常)是一种静态类型语言。因此,这样的比较总是有问题的。但是:

JavaScript的var关键字与C#的dynamic关键字有些相似。两者都创建一个变量,其类型在运行时才会被识别,并且直到运行时才会发现其误用。这是JavaScript 始终的方式,但这种行为对C#4来说是全新的。

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

JavaScript没有任何东西可以匹配C#的var,因为JavaScript是一种动态类型语言,而C#的var尽管有流行的误解,却会创建一个类型在编译时已知的变量。 C#的var有两个目的:声明类型很难写出的变量,以及创建匿名类型的变量,因此 没有可以写出的类型由开发商。

第一个例子:

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();

会导致编译器错误,因为您将connresults设置为与声明为的类型不兼容的类型STRONG>。

答案 1 :(得分:10)

a)C#的var允许你避免在变量声明时写一个显式类型。这使得您的代码更紧凑,有时候声明右侧的表达式类型也很复杂,同时您对实际类型不感兴趣。

b)Javascript var就像C#的dynamic。它允许您声明变量,但您可以更改其类型。

var i = 1; 
i = "foo";  // legal in Javascript, illegal in C#

答案 2 :(得分:7)

他们唯一的共同点是它们用于声明局部变量。

JS var的C#等价物是dynamic。但由于大多数C#用户更喜欢静态类型,因此它通常仅用于某种​​互操作场景(使用COM或动态类型语言)。

C# var仍然使用静态类型,但使用推断类型。由于JS仅支持动态类型,因此没有等效的。

在此上下文中,无法显式静态类型,因为new {mft.CompanyID, mft.CompanyName}会创建anonymous type,因此使用var隐式静态类型。

答案 3 :(得分:1)

var in 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);
}

答案 4 :(得分:0)

要回答您的问题 1 ,在显示的代码中使用var关键字的好处可能很难找到LINQ查询的结果类型,并且可能是容易受到查询更改的影响。事实上,它对C#的介绍恰逢LINQ的首映。

重申,这是为了让程序员的生活更轻松,同时也消除了Type t = new Type()的冗余。