Edw*_*uay 10 c# implicit-typing
在我正在阅读的一本书中,它指出隐式类型使得以下代码比不使用var关键字时更清晰:
var words = new[] { "a", "b", null, "d" };
foreach (var item in words)
{
Console.WriteLine(item);
}
Run Code Online (Sandbox Code Playgroud)
在我看来,情况正好相反:如果您使用了string,那么代码的读者会立即知道它是foreach循环中的字符串,而不必查找定义变量的代码.
隐式类型如何使上面的代码更清晰?
这本书是C#3.0 - Die Neuerungen.schnell + kompakt是德语,实际文本是:
Das Schluesselwort var kann auch beim Durchlaufen von foreach-Schleifen verwendet werden,um somit den Code uebersichtlicher und einfacher zu gestalten.Besonders bei komplexen Typen kann man auf diese Art und Weise Programmierfehler verhindern.
这是我的翻译:
在遍历foreach循环时也可以使用var关键字,从而使代码更容易和更简单地创建.特别是在使用复杂类型时,这可以防止编程错误.
好吧,现在更仔细地阅读它,他实际上声明var在foreach循环中使代码更容易创建但不一定更容易阅读.
Mat*_*t B 11
就个人而言,我同意你的看法.我不确定我会使用的单词是否更清晰,但在某些情况下,var关键字肯定会使它更清晰,即:
var myClass = new ExtremelyLongClassNameIWouldntWantToTypeTwice();
Run Code Online (Sandbox Code Playgroud)
Jul*_*anR 11
我认为奇怪的是,只有C#和Java程序员似乎遭受了阻止他们从代码上下文中提取信息的痛苦,而Python,JavaScript,Ruby,F#,Haskell和其他人的开发人员似乎对此免疫.为什么他们似乎做得很好,但我们C#程序员需要进行这样的讨论?
如果上述显式类型声明是草率或懒惰,这是否意味着没有高质量,可读的Python代码?事实上,没有多少人称赞Python具有可读性?有许多事情让我对JavaScript中的动态类型感到不满,但缺乏显式类型声明并不是其中之一.
静态类型语言中的类型推断应该是常态,而不是例外; 它减少了视觉上的混乱和冗余,同时使你的意图更加清晰,当你做,因为你要少派生类型显式指定类型(IList<int> list = new List<int>();).
有些人可能会反对var这样一个案例:
var c = SomeMethod();
Run Code Online (Sandbox Code Playgroud)
那么,我要说你应该给你的变量更明智的名字.
改进:
var customer = SomeMethod();
Run Code Online (Sandbox Code Playgroud)
更好:
var customer = GetCustomer();
Run Code Online (Sandbox Code Playgroud)
让我们尝试显式输入:
Customer customer = GetCustomer();
Run Code Online (Sandbox Code Playgroud)
您现在拥有的以前没有的信息是什么?你现在知道它的类型Customer,但你已经知道了,对吧?如果您已熟悉代码customer,则只需通过变量名称即可知道可以使用的方法和属性.如果您还不熟悉代码,则不知道有什么方法Customer.这里的显式类型没有增加任何价值.
也许有些反对者var可能会承认,在上面的例子中,var没有任何伤害.但是,如果一个方法不返回一个简单且众所周知的类型Customer,或者Order,但是某些处理过的值,比如某种字典呢?就像是:
var ordersPerCustomer = GetOrdersPerCustomer();
Run Code Online (Sandbox Code Playgroud)
我不知道返回什么,可能是字典,列表,数组,真的.但这有关系吗?从代码中,我可以推断出我将拥有一个可迭代的客户集合,其中每个客户Customer又包含一个可迭代的集合Order.我真的不在乎这里的类型.我知道我需要知道什么,如果事实证明我错了,那就是误导我的名字的方法的错误,这是一个无法通过显式类型声明修复的东西.
让我们看一下显式版本:
IEnumerable<IGrouping<Customer,Order>> ordersPerCustomer = GetOrdersPerCustomer();
Run Code Online (Sandbox Code Playgroud)
我不了解你,但我发现从这里提取我需要的信息要困难得多.丝毫不因为包含的实际信息(变量名),该位为进一步向右,在那里将我的视线更长的时间才能找到它,所有那些疯狂的视认<和>.实际的类型是没有价值的,它是gobbledygook,特别是因为要理解它,你需要知道这些泛型类型的作用.
如果在任何时候你不确定方法做了什么,或者变量包含什么,只要从名称中,你应该给它一个更好的名字.这比查看它的类型更有价值.
不应该需要显式输入,如果是,则代码有问题,而不是类型推断.它不是必需的,因为其他语言显然也不需要它.
也就是说,我确实倾向于使用"基元"的显式类型,比如int和string.但老实说,这更像是一种习惯,而不是一种有意识的决定.但是对于数字,如果您忘记将类型推断添加m到要输入的文字数字中,类型推断可能会使您感到困惑decimal,这很容易做到,但编译器不会让您意外地丢失精度,因此它不会一个实际的问题.事实上,如果我var在任何地方使用它,它会在大型应用程序中进行数量更改,从整数到十进制数字更容易.
这是另一个优点var:它允许快速实验,而不必强迫您更新各地的类型以反映您的更改.如果我想更改上面的示例Dictionary<Customer,Order>[],我可以简单地更改我的实现,并且所有调用它的代码var将继续工作(好吧,至少是变量声明).
在这种情况下它不会,这当然是我的主观意见.我只在类型位于同一行的其他位置时使用它,例如:
var words = new List<String>();
Run Code Online (Sandbox Code Playgroud)
我喜欢var,但我不会像你的例子那样使用它,因为它不清楚类型是什么.
从更少的噪音/冗余感来看,它更清晰.编译器和开发人员都words可以通过new[] { ... }语句轻松推断出类型.所以用来代替,因为后者可以在视觉上混乱代码.varstring[]
从透明度的角度来看,它更清晰.您可以将实际值与任何其他类型的实例交换,只要它是可枚举类型即可.如果您没有使用var,则必须更改示例中的两个声明语句.
它更清楚,因为它迫使你使用好的变量名.通过使用var,您不能使用类型声明来指示变量的内容,因此您必须使用描述性名称.您只需要声明一次变量,但是您可以多次使用它,因此最好能够通过它的名称来计算变量的内容.从这个角度来看,word这将是循环变量名称的更好选择.
请注意,上述推理是从作者的角度进行的.它不一定反映我的个人意见:)
正如我之前提到的,您可以交换底层集合类型,而无需更新所有foreach循环.这样可以更轻松地创建和更改代码,但不一定能防止编程错误.在我们引入一个Word类作为普通字符串的替换之后,让我们看看这两种情况:
如果我们不使用var关键字,编译器将捕获错误:
var words = new[] { new Word("a"), new Word("b"), null, new Word("d") };
// The compiler will complain about the conversion from Word to string,
// unless you have an implicit converion.
foreach (string word in words)
{
Console.WriteLine(word);
}
Run Code Online (Sandbox Code Playgroud)
如果我们不使用var,该代码将编译没有错误,但该程序的输出将是完全不同的,如果Word类有没有(正确)来实现ToString().
var words = new[] { new Word("a"), new Word("b"), null, new Word("d") };
foreach (var word in words)
{
Console.WriteLine(word); // Output will be different.
}
Run Code Online (Sandbox Code Playgroud)
因此,在某些情况下,使用时可能会引入细微的错误var,否则编译器会捕获这些错误.