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 );
这里results
是IQueryable<SomeTypeTheCompilerCreatedOnTheFly>
类型。无论您多么想写出结果的实际类型,而不是仅仅写var
,都没有办法,因为您不知道编译器正在为您的匿名类型创建的类型——因此术语:这种类型是匿名
在这两种情况下,类型在编译时是已知的,并且在这两种情况下,随后都说要么
conn = new DateTime();
或
results = new DateTime();
将导致编译器错误,因为您将conn
和results
设置为与它们声明为的类型不兼容。
【讨论】:
很好的答案!如果微软使用 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实现的区别的主要内容,如果未能解决你的问题,请参考以下文章