Javascript和C#中var实现的区别

Posted

技术标签:

【中文标题】Javascript和C#中var实现的区别【英文标题】:Difference between the implementation of var in Javascript and C# 【发布时间】:2012-01-17 11:20:54 【问题描述】:

我想问一个理论问题。例如,如果我在 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;
               // ...

问题:

    此代码使用var 关键字。这种结构有什么好处? 在 javascript 和 C# 中实现var 的主要区别是什么?

【问题讨论】:

你不妨问问英文“die”和德文“die”的区别。一个是动词 to death 和 dice 的单数,另一个是冠词和代词(在这两种情况下,我只是选择了两个常见的含义,当然还有更多)。它们是完全不同的东西(它们甚至有不同的发音),写下来时碰巧看起来一样。与 C# 和 JS 中的 var 类似。 【参考方案1】:

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

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

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

【讨论】:

【参考方案2】:

为了回答您的问题1,在提供的代码中使用var 关键字的好处是可能很难为 LINQ 查询提供结果类型,并且很容易受到影响通过对查询的更改。事实上,它对 C# 的介绍恰逢 LINQ 的首次亮相。

重新假设,是为了让程序员的生活更轻松,也是为了去除Type t = new Type()的冗余。

【讨论】:

【参考方案3】:

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 或实体框架的匿名类型投影是第二个很好的例子:

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

这里resultsIQueryable<SomeTypeTheCompilerCreatedOnTheFly> 类型。无论您多么想写出结果的实际类型,而不是仅仅写var,都没有办法,因为您不知道编译器正在为您的匿名类型创建的类型——因此术语:这种类型是匿名

在这两种情况下,类型在编译时是已知的,并且在这两种情况下,随后都说要么

conn = new DateTime();

results = new DateTime();

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

【讨论】:

很好的答案!如果微软使用 infer 这个词而不是 var 会更准确,但为了简洁起见,我认为他们选择了正确的词。这么多年过去了,与其他开发技术相比,.NET 的优雅程度仍然让我感到惊讶。我猜是微软开发团队不得不吃自己的狗粮。顺便说一句,如果你使用 Resharper,var 的工作原理就会立即显现出来。 @Joel,谢谢,是的,我发现 C# 非常优雅。 Eric Lippert 和他的公司做得很好。 @Joel:C# 的唯一问题是它是基于 C 的,因此它带来了许多来自 C 的糟糕语法选择。当然,如果它不是基于 C 的,它几乎没有采用率,所以 正确的选择...这是编程社会的问题,而不是 C# 设计者的错误:\ 另外,JavaScript 中的 var 关键字对变量类型没有任何作用,但它确实会影响变量范围。没有 var 声明的变量成为全局变量。使用 var 关键字声明的一种是局部的(在 JavaScript 中,即函数作用域,而不是块作用域)。 @Johan - 非常正确。 C# 没有隐式全局变量的等效项。【参考方案4】:

C# 中的 var 在设计时是动态的,但在编译时是静态类型的。如果你这样做,你会看到:

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

【讨论】:

“设计时间”是什么意思?【参考方案5】:

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

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

C# var 仍然使用静态类型,但使用推断类型。由于 JS 只支持动态类型,所以没有等价的。

在这种情况下,显式静态类型是不可能的,因为new mft.CompanyID, mft.CompanyName 创建了一个anonymous type,所以使用var 的隐式静态类型。

【讨论】:

以上是关于Javascript和C#中var实现的区别的主要内容,如果未能解决你的问题,请参考以下文章

c#中的var关键字和object关键字的区别,顺便介绍下object的使用方法以及好处。

C#与JavaScript的语法区别

C#中“var”和“object”之间的区别[重复]

javascript中类式继承和原型式继承的实现方法和区别

C#中的object和var区别

“C++ void Pointer”和“C# var”之间的区别