【问题标题】:Difference between the implementation of var in Javascript and C#Javascript和C#中var实现的区别
【发布时间】: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};
               // ...

问题:

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

【问题讨论】:

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

标签: c# javascript .net linq 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 的隐式静态类型。

      【讨论】:

        猜你喜欢
        • 2017-01-17
        • 2011-05-28
        • 1970-01-01
        • 2017-04-08
        • 1970-01-01
        • 2014-03-15
        • 2018-08-02
        • 2015-01-29
        • 1970-01-01
        相关资源
        最近更新 更多