代码之家  ›  专栏  ›  技术社区  ›  Spoike Otávio Décio

为什么var是一件坏事?

  •  47
  • Spoike Otávio Décio  · 技术社区  · 15 年前

    var C#中的关键字。他们不知道为什么会这样,我总是发现隐式声明在编码时非常有用。我在找出变量的类型时从来没有遇到过任何问题(您只需将鼠标悬停在VS中的变量上,就可以得到该类型)。

    有人知道为什么在C#中使用var关键字是个坏主意吗?

    17 回复  |  直到 14 年前
        1
  •  72
  •   Renaud Bompuis    12 年前

    《圣经》的作者 .Net Framework Design Guidelines 2008年11月出版的一本很棒的书建议考虑使用 var 当类型明显且明确时。

    另一方面,如果使用 变量 正如安东·戈戈列夫(Anton Gogolev)指出的那样,在阅读代码时会导致歧义,那么最好不要使用它。

    var names = new List<string>(); // good usage of var
    
    string source = GetSource();
    var tokens = source.Split(' '); // ok; most developers know String.Split
    
    var id = GetId(); // Probably not good; it's not clear what the type of id is
    

    有可能,为了确保可读性不受低级开发人员的突发奇想的影响,您的组织认为您不值得这样做 并且禁止了它。

    在大多数情况下,使用 变量 对于简单类型,实际上有助于可读性,我们不能忘记,使用 .

        2
  •  34
  •   Anton Gogolev    15 年前
    var q = GetQValue();
    

    var persistenceManager = ServiceLocator.Resolve<IPersistenceManager>();
    

    底线是:使用描述性的标识符名称,你会相处得很好。

    作为旁注:我想知道当不允许使用匿名类型时,它们如何处理匿名类型 var

        3
  •  21
  •   Marc Gravell    15 年前

    在大多数情况下,当明智地使用(即类型和值相同的简单类型初始值设定项)时,就可以了。

    • 该变量最初是一个接口
    • 该变量最初是另一种类型,带有隐式转换运算符

    在这些情况下,您可能会遇到任何类型解析的问题,例如:

    • 对两种竞争类型具有不同重载的方法
    • 泛型类型推断的工作方式不同
    • 操作员分辨率将以不同的方式工作

    示例:

    static void Main() {
        long x = 17;
        Foo(x);
        var y = 17;
        Foo(y); // boom
    }
    static void Foo(long value)
    { Console.WriteLine(value); }
    static void Foo(int value) {
    throw new NotImplementedException(); }
    

    方法隐藏:

    static void Main() {
        Foo x = new Bar();
        x.Go();
        var y = new Bar();
        y.Go(); // boom
    }
    class Foo {
        public void Go() { Console.WriteLine("Hi"); }
    }
    class Bar : Foo {
        public new void Go() { throw new NotImplementedException(); }
    }
    

        4
  •  18
  •   NeedHack    15 年前

        5
  •  10
  •   Daniel Daranas    15 年前

    其次,这条规则可能是合理的,因为 代码读的次数比写的次数多 var 加快书写速度,但可能会减慢阅读速度。这显然不是像“总是初始化变量”这样的代码行为规则,因为这两个选项(编写 变量 变量 ,我只会用“更喜欢…”

        6
  •  8
  •   JaredPar    15 年前

    1. 它不会降低类型安全性
    2. 它会提醒您隐式强制转换,从而提高代码中的类型安全性。foreach语句中的最佳示例
    3. 保持C#中的干燥原则。这是专门针对声明案例的,为什么还要麻烦说两遍这个名字呢?
    4. 在某些情况下,这是完全必要的。匿名类型示例
    5. 输入更少,功能不会丢失。

    http://blogs.msdn.com/jaredpar/archive/2008/09/09/when-to-use-type-inference.aspx

        7
  •  6
  •   Garry Shutler    15 年前

    var

    你的朋友很不幸,他们在一个极端分子手下工作。

        8
  •  5
  •   ShuggyCoUk    15 年前

    完全禁止它意味着禁止使用匿名类型(随着LINQ的使用越来越多,匿名类型变得非常有用)。

    除非有人能正式提出一个不使用匿名类型的好理由,否则这就是愚蠢的简单明了。

        9
  •  5
  •   Luis Perez    5 年前

    我将向您展示使用和不使用“var”是关于清晰地沟通的。

    我将展示使用“var”使代码更易于阅读的示例,以及使用var使事情难以理解的其他示例。

    更重要的是,您将看到“var”的清晰程度在很大程度上取决于您对代码中其他所有内容的命名。

    杰克向比尔问好。他不喜欢他,所以他转身走了另一条路。

    谁走了另一条路?杰克还是比尔?在本例中,“Jake”和“Bill”类似于类型名称。“他”和“他”就像var关键字。在这种情况下,更具体一些可能会有所帮助。下面的例子更清楚。

    杰克向比尔问好。杰克不喜欢比尔,所以他转身走了另一条路。

    比尔喜欢书,所以比尔去了图书馆,比尔拿出了一本比尔一直喜欢的书。

    var 关键词。

    比尔喜欢书,所以他去了图书馆,拿出了一本他一直喜欢的书。

    这些类比涵盖了要点,但不能说明全部情况。在这些例子中,提到这个人只有一种方法。要么用他们的名字,比如比尔,要么用更一般的方式,比如“他”和“他”。但我们只是在用一个词。

    对于代码,您有两个“单词”,类型和变量名。

    Person p = GetPerson();
    

    p 是您是否仍然知道此场景中的人员:

    var p = GetPerson();
    

    这个怎么样:

    var p = Get();
    

    这个怎么样:

    var person = Get();
    

    var t = GetPerson();
    

    或者这个:

    var u = Person.Get();
    

    关键词是否正确 变量

    变量 . 但是我也倾向于以类型命名变量,这样我就不会丢失任何信息。

        10
  •  4
  •   Andrew Hare    15 年前

        11
  •  4
  •   user1023602 user1023602    7 年前

    你可以认为微软的观点是相关的,因为C语言是他们的语言:

    “但是 变量 至少有可能让其他开发人员更难理解您的代码。因此,C#文档通常使用 变量 只有在需要的时候。”

    MSDN - Implicitly Typed Local Variables (C# Programming Guide)


    你也应该意识到 变量

    var x = "mistake";     // error not found by compiler
    int x = "mistake";     // error found
    

    由于大多数变量只分配一次,因此 删除变量分配上几乎所有的数据类型测试。

    这使得您的代码容易受到意外更改的影响,例如合并工具或疲惫的开发人员所做的更改。

        12
  •  3
  •   CraigTP    15 年前

    我个人的偏好是只对匿名类型使用“var”(事实上,如果你想使用匿名类型,你需要使用var),而这些大多来自LINQ查询。在这些情况下,如果查询投影到一个新的(隐式&匿名)类型,那么您别无选择,只能使用var。

    然而,C#3.0很乐意让您在LINQ和匿名类型之外的任何地方使用var,例如:

    var myint = 0;
    var mystring = "";
    

    是完全有效的,myint和mystring将由用于初始化它们的推断值强类型化。(因此,myint是System.Int32,mystring是System.String)。当然,当查看用于初始化变量的值时,很明显它们将被隐式类型化为什么类型,但是,我认为如果将上述内容编写为:

    int myint = 0;
    string mystring = "";
    

    考虑一下这个令人困惑的场景:

    var aaa = 0;
    double bbb = 0;
    

    完全有效的代码(如果有点非常规),但是在上面,我知道bbb是一个double,尽管初始化值看起来是int,但是aaa肯定不是double,而是int。

        13
  •  2
  •   Mark Rendle    15 年前

    隐式类型是很好的,坚决禁止隐式类型的人会损害生产力,并导致代码脆弱。

    这几乎就像类型安全、编译器检查的duck类型,在重构时非常有用。例如,如果我有一个返回列表的方法,并且我重构它以返回IEnumerable,那么使用var关键字并且只使用IEnumerable方法的方法的任何调用方都可以。如果我已经明确指定了,例如,List,那么我必须去把它改为IEnumerable everywhere。

    显然,如果任何隐式类型调用者需要列表方法,那么在构建时我将得到编译错误,但是如果是这种情况,我可能不应该改变返回类型。

        14
  •  2
  •   Chris S    12 年前

    利珀特 sums it up well :

    • 必要时使用var;当您使用匿名类型时。
    • 如果代码强调变量的语义“业务目的”,并且淡化其存储的“机械”细节,则考虑使用var。
    • 如果要正确理解和维护代码,必须使用显式类型。
    • 无论是否使用“var”,都要使用描述性变量名。变量名应该代表变量的语义,而不是其存储的细节;“小数”是坏的;“利率”很好。

    我个人的看法是:我发现阅读起来更难,而且对于诸如 int string , bool User . 毕竟,它是关于可读性的(除了与LINQ一起使用它的地方),所以当变量被散播时,它可能更难阅读,并且违背了语言设计者想要的关键字的目的。

        15
  •  2
  •   waka    7 年前

    从…起 Department of Declaration Redundancy Department (来自杰夫的 Coding Horror

    “我使用隐式变量类型 无论何时何地,它都会生成我的代码 更简洁。任何可以移除的东西 我们的代码中的冗余应该是 积极追求——达到和 包括交换语言。”

    我自己也这么认为 .

        16
  •  1
  •   Ries    15 年前

    我曾经遇到过这样的情况(当我通过Table.Rows集合foreach时),使用var导致类型为某个基类而不是实际的DataRow类型。这是我唯一一次在var上遇到麻烦。

        17
  •  -4
  •   saluce jkm    12 年前

    下面是我对效率的测试结果 var

      private void btnVar_Click(object sender, EventArgs e)
        {
            Stopwatch obj = new Stopwatch();
            obj.Start();
            var test = "Test";
            test.GetType();
            obj.Stop();
            lblResults.Text = obj.Elapsed.ToString();
        }
    
        private void btnString_Click(object sender, EventArgs e)
        {
            Stopwatch obj = new Stopwatch();
            obj.Start();
            string test = "Test";
            obj.Stop();
            lblResults.Text = obj.Elapsed.ToString();
    
        }
    

    第一个标签结果是:00:00:00 000034

    推荐文章