C# 为什么需要申报

C# 为什么需要申报,c#,.net,variables,clr,declaration,C#,.net,Variables,Clr,Declaration,我目前正在教一位同事.Net,他问了我一个让我难堪的问题 我们为什么要申报 如果var是隐式类型,为什么还要声明呢 Animal animal = new Animal(); 变成 var animal = new Animal(); 可能成为 animal = new Animal(); 隐式类型仍然意味着这是一个静态类型的变量 如果为变量分配了两种不同的类型,如果它们不共享基类(对象除外),则可能是编译器错误 是否有技术上的原因无法做到这一点,或者是我们喜欢的风格,当然,这是可能的 我

我目前正在教一位同事.Net,他问了我一个让我难堪的问题

我们为什么要申报

如果var是隐式类型,为什么还要声明呢

Animal animal = new Animal();
变成

var animal = new Animal();
可能成为

animal = new Animal();
隐式类型仍然意味着这是一个静态类型的变量

如果为变量分配了两种不同的类型,如果它们不共享基类(对象除外),则可能是编译器错误

是否有技术上的原因无法做到这一点,或者是我们喜欢的风格,当然,这是可能的

我可以想出一些你不想要这个的原因:

  • 变量的范围是什么?如果你不告诉编译器,就不清楚了。两个方法中的
    animals
    会成为私有变量还是两个方法范围内的变量
  • 如果名字是打字错误怎么办?你永远不会知道
  • 如果您已经为此变量分配了一个值,然后尝试分配一个与上一个(即javascript样式)不兼容的新值(credits to),该怎么办

  • 一个非常重要的原因是,它有助于防止因意外错误键入变量名而导致的错误

    想象一下,您想重新分配string
    myString
    以获得一个新值:

    myString = "New value";
    
    但您不小心键入了以下内容:

    myStrimg = "New value";
    

    这将导致编译时错误。但是,如果您允许为每个问题隐式创建变量,这将无声地创建一个新变量,并产生可以预见的有趣结果…

    正如Brad Smith所建议的那样:-

    有些程序员似乎倾向于在每种情况下都使用var 变量声明。当然,语言并不能阻止你这么做 事实上,MSDN承认这是一种“语法上的便利”… 但它也非常强烈地警告说:

    var的使用至少有可能使您的代码更加复杂 其他开发人员很难理解。因此,C# 文档通常仅在需要时才使用var

    隐式类型局部变量(C#编程指南),MSDN

    我最近发现常用的工具ReSharper 实际上要求自由使用var。坦率地说,这没有帮助 情况。有一些开发人员试图论证这一立场 var以某种方式提高了可读性和更广泛的编码实践, 例如本文:

    通过使用var,您迫使自己更多地思考如何 命名方法和变量,而不是依赖类型系统 提高可读性,这更像是一个实现细节

    var提高了可读性,Hadi Hariri

    我同意上面引用的前提,但不同意结尾 结果。相反,过度使用和滥用var会导致 一些非常坏的习惯

    让我们来看一下反对广泛使用var(以及 其备用、正确使用):

    隐式类型变量失去了描述性

    类型名称在局部变量声明中提供了一个额外的描述层:

    我上面的变量名是完全描述性的;它区别于 在使用GetContacts()填充的任何其他变量之间 DataTable类型的其他变量。当我操作变量时,我 要知道我指的是个人接触,而且 我从他们那里得到的任何东西都将是这种情况。然而,没有 在声明中指定类型名称时,将丢失 它提供的描述性

    当我重温这段代码时,我不仅知道 变量在概念上表示,但也在术语上表示 结构和用法的变化;上一个例子中缺少的东西

    附加说明:-

    这里有几个基于隐式变量声明的合理使用的好/坏示例

    • 好:

       var numbers = new int[] {1, 2, 3, 4};
      
       var stringbuilder = new StringBuilder();
      
       var cars = new List();
      
       var orders = new Dictionary();
      
    +/-可以(但更喜欢显式声明):


      原因一定很多。我能想到的一个原因是属性/字段引用与新变量之间的模糊性


      然而,C#编译器团队可能仍然可以开发这样的功能。但使用var简化了一切。我们节省了设计工作、开发工作、测试工作和维护工作。最重要的是,它使您的代码更具可读性

      当我们声明一个变量时,我们向我们的工具指出以下内容

      • 为物品腾出空间
      • 将生活在这个范围内
      • 并且属于这种类型(可选)
      我们对人类说的是

      • 此作用域中存在名为xxx的对象
      • 此类型(可选)
      范围对于这两个方面都是至关重要的,因为工具需要知道变量将存在多长时间,并且人类需要了解变量的存在位置。这个类型可能是一个很好的信息,但是很多语言都没有它,所以我认为它没有那么重要,但是很重要

      编译器可以确定变量的作用域,例如,通过确定变量名的第一次相遇是变量的声明,以及下面具有相同名称的任何单词是对该变量的引用。另一方面,人类无法成功地跟踪这种复杂性


      所以我想说,我们有一个很好的理由来声明变量:告诉阅读我们代码的人它存在。声明变量增加了它们的可视性,并澄清了对我们理解程序至关重要的信息。

      好吧,我不反对在这里的一些答案中提出的事实。相反,我想以不同的方式回答:

      int count;
      if(someConditionIsTrue)
          count = 3;
      else count = 1;
      
      我不能在这里使用“var count”。可以
       var numbers = new int[] {1, 2, 3, 4};
      
       var stringbuilder = new StringBuilder();
      
       var cars = new List();
      
       var orders = new Dictionary();
      
       int pages = 10;
       string username = “john”;
      var username = “john”;
      var order = GetOrder(orderId); // ok if the type is Order, otherwise not
       for (var x = 1; x < 10; x++)
      
         var settings = GetInboxSettings(); // not obvious at all
      
        var userId = GetUserId(); // ambigous, is this guid, string, int or a custom UserId object?
      
         Dictionary orders = new Dictionary(); // redundant
      
      int count;
      if(someConditionIsTrue)
          count = 3;
      else count = 1;
      
      Tuple<int, string, bool, float> tuple = new Tuple<int, string, bool, float>(1, "p", true, 3.0f);
      
      var tuple = new Tuple<int, string, bool, float>(1, "p", true, 3.0f);