我知道问题的标题是非常主观的,但是??
我的同龄人遇到了使用运算符的问题,而与此同时,我对申请var
新的即将出现的代码并不满意/不满意。
使用??
operator 给出的参数是,它占用了代码的可读性。
我的问题是,开始使用时会发生同样的事情var
吗?
我知道问题的标题是非常主观的,但是??
我的同龄人遇到了使用运算符的问题,而与此同时,我对申请var
新的即将出现的代码并不满意/不满意。
使用??
operator 给出的参数是,它占用了代码的可读性。
我的问题是,开始使用时会发生同样的事情var
吗?
Answers:
就个人而言,我认为使用此运算符没有任何不利影响。考虑以下三个代码示例,从“简单”到“复杂”新运算符。
没有魔术:
bool isNameSet = false;
string name;
if ( isNameSet )
{
Console.WriteLine( name );
}
else
{
Console.WriteLine( "No name set." );
}
三元运算符:
bool isNameSet = false;
string name;
Console.WriteLine( isNameSet ? name : "No name set." );
空合并:
string name = null;
Console.WriteLine( name ?? "No name set." );
这些运算符之所以被发明是因为它们代表了非常普通的编程操作。因为您不习惯它们而不想使用它们只是固执。语言在发展,功能在发展,学会使用它们!
我对var关键字有不同的看法。变量的类型通常会提供有关代码的更多信息。我发现使用var关键字隐藏类型有时会使代码的可读性降低。在不使用自动完成功能或将标识符悬停在标识符上以查看其实际含义的情况下,您所知不多。在我看来,这导致代码的读取/写入速度较慢。
当我发现类型没有提供太多额外信息时,我确实使用了关键字。
作为最后一条语句的示例:
ThisIsSomeSpecializedTypeRightHere duplication =
new ThisIsSomeSpecializedTypeRightHere();
var justAsReadable =
new ThisIsSomeSpecializedTypeRightHere(); // Less duplication.
// But I still prefer the following ...
int number = 9;
SomeCreatedType foo = Factory.CreateSomeType();
Factory.CreateSomeType
返回IEnumerable<SomeType>
。有一天,无论出于什么原因,它都会变回去SomeType[]
。如果您使用过var,那只是重新编译。
Factory.CreateSomeType()
更改返回值ISomeType
怎么办?
null
完全避免不可避免。此外,我寻找的替代品null
越多,null
有时我意识到使用的是最干净的解决方案。我给定的例子并不是那么糟糕,恕我直言,我发现它是可空类型的适当用法。
var允许使用更少的冗长代码,从而增加了可读性。我认为,可读性不应该用看到的细节来衡量,而应该乍一看就隐藏了多少细节。除了Linq示例,var还允许在源代码级别进行鸭子输入,如下例所示:
...
foreach (var message in messages) {
var label = Factory.CreateLabel();
label.Text = message;
Controls.Add(label);
}
...
谁在乎标签的类型是什么,只要它提供Text属性?
我对??
运算符没有任何严肃的评论,因为我从未在这样的运算符上大量使用过一种语言。关于var
,人们使用Ruby,Python,Perl和PHP这样的语言进行编程,这些语言始终具有完全隐式的输入。这些语言的本地人意识到,变量的形式类型通常是无关紧要的。您对变量可以做什么更感兴趣,即它的结构/鸭子接口。
同样,我主要使用D进行编程。D是静态类型的,但具有auto
关键字,它等效于var
。除非您看到需要向阅读器或(通过隐式转换)编译器强调某种类型的特殊需求,否则在任何地方都使用它被认为是惯用的。除了偶尔用作函数返回类型(在D中允许)外,我从未发现它会妨碍可读性,因为在我编程时,我主要是考虑结构/鸭子接口,而不是形式/标称类型。
此外,恕我直言var
,尽可能地使用DRY就是一个很好的例子。事物的类型应在一个且只能在一个地方指定,然后在需要传播时自动传播。如果您使用var
并且变量的形式类型需要在某个时候进行更改,则只要程序仍然是类型正确的,必要的更改将自动传播到编译器需要的所有地方,而程序员不必手动更改每个实例。这是一件好事(TM)。
我认为这最终是团队的问题。如果我的团队中的其他任何人都看不懂它,那么我将不会使用它,尽管我可能会尝试几次用示例来说服他们,或者指出类似的缩写(例如+ =),以使它们更易读。
但是,如果独自工作,我会发现?? 和var无限制地可读。甚至
var a = b ?? c ?? d ?? e ?? "";
对我来说很明确。
dynamic
当然,三元运算符是另一回事。
var a = b ?? c ?? d ?? e ?? String.Empty ?? "";
String.Empty
返回null
,我们将陷入很多破损代码的泥潭。
使用??给出的参数 运算符是,它消除了代码的可读性。
简短地思考一下,此评论告诉我进行评论的人,对它的理解不尽如人意。在某些情况下,这很可能是正确的,但是总的来说,我不反对C#团队显然出于“可读性”而认为足够重要的东西。我把它放在if(boolean_object)
vs 的同一类别中
if(boolean_object == true)
。有人认为第二个代码更具可读性,但实际上,它只是添加了一些额外的代码供他人阅读/输入,在某些情况下可能会更加令人困惑(请思考if(boolean_object != false)
)
我的问题是,当您开始使用var时会发生同样的事情吗?
C#团队允许您不定义某些东西,而这些东西您将要知道。除非我绝对不需要定义变量将是什么(返回对象的类型为x绝对重要,或者它实际上是不可读的),否则我会使用var
。
var x = "MY_STRING";
我知道这是一个字符串。实际上,只要它满足我的要求,我就不会在乎它是字符串。定义变量类型是为了我的利益,而不是编译器的利益。如果出现问题,如果变量类型错误,编译器会告诉我何时运行。
var
在我看来,该关键字最好在最初引入的情况下使用-LINQ查询。在这些查询中,返回结果的类型通常具有一些复杂的名称,很难事先确定,并且不利于读者理解代码的作用。
但是,这样做var text = "Some text " + variableName + "some more text."
只是懒惰。
编辑:@Jorg您跳了一个有目的的简单答案,但没有添加任何讨论。好的,如何做一个更好的例子:var items = doc.DocumentElement.FirstChild.ChildNodes;
如果您能从中找出类型,我给您一个cookie。
"Some text "
是一个string
,那么您要担心的问题比var
代码中s 的数目大得多。
var
; 问题是糟糕的变量名称“ items”。如果您使用好的变量名,那么没什么问题var
。
我在使用var时遇到一个基本问题。
在此示例中,所有内容都是并行的,但是问题实际上是共享库或项目的大型解决方案。
考虑一下:
public MyFirstObject GetMeAnObject() {
return new MyFirstObject();
}
public void MainProgram() {
var theObject = GetMeAnObject();
theObject.PerformOperation();
}
如果其他人更改了GetMeAnObject以适应他们的需求会怎样?
public MySecondObject GetMeAnObject() {
return new MySecondObject();
}
MainProgram方法在.PerformOperation()上将有一个大的红色错误。发生了什么?PerformOperation之前运行得很好。我们看一下对象上的方法,它消失得无影无踪。上次在那里,我们需要那种方法。您可能需要花费很长时间来追尾,并试图找出原因,如果MyFirstObject有一个名为PerformOperation的方法,则现在看不到它。每个人都“知道” GetMeAnObject返回了MyFirstObject,因此毫无意义地进行检查。
如果您已显式键入theObject,则在调用GetMeAnObject的行上将出现Invalid Cast错误,并且很明显,GetMeAnObject返回的类型不是您期望的类型。
简而言之,显式声明意味着您知道错误的含义。无效的强制转换意味着您期望一种类型,而返回了另一种类型。无法识别的成员表示该成员未被识别。
var
哪里?不能指望该语言能够防止这种行为-如果他们直接修改MyFirstObject会怎样?它仍然会坏掉,但是没有语法可以使您摆脱困境。我var
甚至认为这是一个优势:如果不是现在返回IMyFirstObject而不是返回MySecondObject,该怎么办?
??
在解释后无法理解null合并运算符,则不应在生产代码附近使用它们。