当前位置:  开发笔记 > 编程语言 > 正文

为什么var会变坏?

如何解决《为什么var会变坏?》经验,为你挑选了8个好方法。

前几天我和同事聊天,听说他们的编码标准明确禁止他们var在C#中使用关键字.他们不知道为什么会如此,我总是发现隐式声明在编码时非常有用.我从来没有遇到任何问题,找出变量是什么类型(你只是将鼠标悬停在VS中的变量上,你会得到那种方式).

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



1> Renaud Bompu..:

2008年11月发布的.Net框架设计指南(精彩的书籍)的作者建议考虑var在类型明显且明确的时候使用.

另一方面,如果使用var会在阅读代码时导致歧义,正如Anton Gogolev指出的那样,那么最好不要使用它.

在书中(附件A),他们实际上给出了这个例子:

var names = new List(); // 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

为了确保可读性不受低级开发人员的影响,您的组织可能已经决定您不值得var并禁止它.
但这很遗憾,它就像拥有一个漂亮的工具,但保存在一个锁着的玻璃柜中.

在大多数情况下,使用var简单类型实际上有助于提高可读性,我们不能忘记使用时也没有性能损失var.


为什么只有在没有额外工作的情况下阅读它时,将鼠标悬停在每个变量上?WTF
@PoweRoy:我认为这是他的观点 - 当明确地输入时,_always_很明显.. long id = GetId();
我认为在这场战争中每个人都错过的最大的想法是"悬停在变量上"我看不到GetId()在这里返回的内容,但是你经常阅读IDE中没有的复杂代码?工具是该语言的重要组成部分.
模糊声明中的`var`对于像bitbucket或github这样的Web UI中的拉取请求评论来说也是一个很大的痛苦.您不能将声明悬停以获取类型.就个人而言,我有一个非常严格的政策:只在操作的另一边使用`new`时使用var(这包括匿名类型)或者使用显式转换时(尽管我在这里也不倾向于使用`var`) .
虽然这样做有意义并且使类型对于阅读代码的人来说更加明显......现在你的声明不一致了.一些隐式和一些显式,只是这样你可以使用变量,当它"显然"更容易.现在我们必须根据代码的显而易见性来看方程式的两边.如果使用显式声明来简化可读性,请通过保持一致性来进一步简化它.此外,无论谁认为人们可以通过用鼠标悬停在隐含的词语上来阅读,都需要再次思考,这只会减慢我们的速度并降低可读性.

2> Anton Gogole..:
var q = GetQValue();

确实是一件坏事.然而,

var persistenceManager = ServiceLocator.Resolve();

对我来说完全没问题.

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

作为旁注:我不知道如果不允许使用var关键字,他们如何处理匿名类型.或者他们不完全使用它们?


我发现通常在重构之后,命名良好的变量指示旧类型并且实际上可能会产生误导.如果类型是明确的,那么很容易发现这种问题.

3> Marc Gravell..:

在大多数情况下,当合理使用时(即类型和值相同的简单类型初始化器),那就没问题了.

有些时候不清楚你是否通过改变来破坏它 - 主要是,当初始化类型和(原始)变量类型不相同时,因为:

变量最初是基类

变量最初是一个接口

该变量最初是具有隐式转换运算符的另一种类型

在这些情况下,您可能会遇到任何类型分辨率的问题 - 例如:

对于两种竞争类型具有不同重载的方法

为两种竞争类型定义不同的扩展方法

已在其中一种类型上重新声明(隐藏)的成员

泛型类型推断将以不同的方式工作

操作员解析将以不同的方式

在这种情况下,您可以更改代码的含义,并执行不同的操作.这是一件坏事.

例子:

隐式转换:

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

等等


另一个例子:改变"Car myCar = BuickFactory.MakeCar;" to"var myCar = BuickFactory.MakeCar;" 如果BuickFactory.MakeCar返回Car,则可能不会更改代码,但如果更高版本的BuickFactory影响MakeCar返回Buick,则myCar变量的类型将会更改.如果运行代码尝试将其他类型的Car分配给myCar,则会失败.

4> NeedHack..:

当然这是一个错误.这是因为有些人并没有意识到它实际上是强类型的,而且根本不像VB中的var.

并非所有的公司编码标准都有意义,我曾经为一家想要在公司名称前加上所有类名称的公司工作过.当公司改名时,进行了大规模的返工.


哎哟! @使用公司名称前缀类名.
你应该感到羞耻,承认你还记得!;-)

5> Daniel Daran..:

首先,作为一般规则,编码标准应该由团队讨论和同意,并且应该写下他们背后的推理,以便任何人都可以知道他们为什么在那里.他们不应该是一位大师的圣洁真理.

其次,这个规则可能是合理的,因为代码读取次数多于写入次数.var加快写作速度,但可能会减慢读数速度.它显然不是像"始终初始化变量"这样的代码行为规则,因为两种选择(写入var和写入类型)具有完全相同的行为.所以这不是一个关键的规则.我不会禁止var,我会使用"首选..."



6> JaredPar..:

几个月前我写了一篇关于这个主题的博客文章.对我来说,我尽可能地使用它,并专门围绕类型推断设计我的API.我使用类型推断的基本原因是

    它不会降低类型安全性

    它实际上会通过提醒您隐式转换来增加代码中的类型安全性.foreach语句中最好的例子

    在C#中维持DRY原则.这是专门针对宣言的案例,为什么还要两次说这个名字呢?

    在某些情况下,它是必需的.示例匿名类型

    减少打字而不损失功能.

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



7> Garry Shutle..:

var是最新的"如何布置你的大括号"/匈牙利符号/骆驼套管辩论.没有正确的答案,但有些人坐在极端.

你的朋友很幸运,他们在一个极端分子之下工作.



8> ShuggyCoUk..:

禁止它完全意味着禁止使用匿名类型(当你更多地使用LINQ时,它变得非常有用).

这是愚蠢的简单和简单,除非有人可以正式确定永远不使用匿名类型的正当理由.

推荐阅读
家具销售_903
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有