Juval Lowy的C#编码标准问题

我很喜欢并强烈推荐Juval Lowy的 – C#Coding Standard 。 Juval明确地避免了每个指令的基本原理,以保持标准的严格(参见前言)。 但是,有一些指令让我对基本原理感到好奇。

来自Lowy的C#标准的以下指令的具体原理是什么?
希望这些答案很难(非主观)。

1.13避免使用完全限定的类型名称。 请改用“using”语句。
这是性能问题吗? 有时我只需要一个完全限定名称的实例,并添加一个看起来很重的使用

1.26在无参数匿名方法上使用空括号。 仅当匿名方法可以在任何委托上使用时,才省略括号。
实际上我只是被第二句话弄糊涂了。 对示例的解释会有所帮助,谢谢。

2.19避免定义自定义exception类
最小化数量有哪些考虑因素? (如果你确定它们,他接下来给出指导(在2.20中)。)

2.29避免使用三元条件运算符
读者难以消化或其他考虑因素?

2.31避免在布尔条件语句中调用函数。 分配到局部变量并检查它们。
我不认为我这样做,但我很好奇……为什么不呢?

2.47避免与一个成员的接口。
因为它总是/通常更优先做什么? 一种方法界面工作时?

2.53首选使用显式接口实现
为什么? 此外, Jon Skeet在这里不同意 。

提前致谢! 罗伯特

显然,我不是Juval,但我可以捅这些

1.13避免使用完全限定的类型名称。 请改用“using”语句。

性能不能成为问题。 我确定这个问题是可读性的。

1.26在无参数匿名方法上使用空括号。 仅当匿名方法可以在任何委托上使用时,才省略括号。

public delegate void Foo1(); public delegate void Foo2(int val); public void Foo() { Foo1 first = delegate { Console.WriteLine("Hello world"); }; Foo2 second = delegate { Console.WriteLine("Hello world"); }; Foo1 third = delegate() { Console.WriteLine("Hello world"); }; Foo2 fourth = delegate() { Console.WriteLine("Hello world"); }; // does not compile } 

没有parens,匿名委托可以应用于任何委托。 对于parens,你是具体的代表签名。 除非您确实需要灵活性,否则请选择第二种语法。

2.19避免定义自定义exception类

同样,可读性是这里的问题。 框架exception类很丰富且易于理解。 更换时要小心。

2.29避免使用三元条件运算符

这是一个可读性和可扩展性的东西。 我真的不同意,但这是一场标准的宗教斗争。

2.31避免在布尔条件语句中调用函数。 分配到局部变量并检查它们。

部分这是可读性,部分是为了便于调试。 我已经开始将几乎所有内容分配给临时变量,以便以后可以在调试器中轻松找到它们。

2.47避免与一个成员的接口。

“避免”有点像“喜欢”,他只是在你做之前先说三思。 如果您只有一个成员,那么界面是否真的在您的设计中建模有用且完整的东西? 只有一个成员的课程很少见,认真考虑为什么你的界面有所不同。

2.53首选使用显式接口实现

这类似于使用最少公共访问器的想法。 如果你的类不需要公开接口,那么它可能不应该。 显然,根据您的设计,这将显着不同,但鉴于大多数人只是在没有真正考虑它的情况下隐藏界面,这是值得考虑的建议。

2.29避免使用三元条件运算符对三元运算符的 “简单”使用没有任何问题,但建议不要以嵌套方式使用它:

 // This is fine x := (conditionA) ? true_resultA : false_resultA; // This would probably be clearer using if-then-elseif x := (conditionA) ? ((conditionA1) ? true_resultA1 : (condition2) ? true_result2 : false_result2) : ((conditionA2) ? true_resultA2 : false_resultA2); 

1.26是关于pre-lambda delegate { }语法。

 // #1 Empty parenthesis on parameterless-anonymous methods would be: delegate() { } // #2 ... anonymous method could have been used on any delegate, is: delegate { } 

请记住,后者可以分配给任何委托,无论其参数如何。 委托只是使用一些编译器技巧忽略了这些。

如果您定义一个不带参数的委托,请使用#1明确说明。 不要“留下括号,因为你的代表无论如何也不会采用任何参数”。

很多这些指南都与良好软件设计“质量属性”相关 (即可维护性,可靠性,可重用性,可测试性,可扩展性,可调试性,互操作性以及您可以命名的其他function)。

通常人们创建当时工作正常的代码,但在考虑所有质量属性时(在“这个软件将来可以哪里”或“其他人也必须使用此代码”的意义上可能不是最佳选择) )。

例如:

2.29避免使用三元条件运算符

我对三元表达式本身没有问题,但是通过编写如下代码: int result = CheckMethod()? OnTrueDoThis():OnFalseDoThat() ……你说,“我有一个条件,如果是真的(或假的),你可以只做一件事 。” 整个结构阻碍了可扩展性 。 您必须重新创建构造(使用if..else语句)。

同样…

2.31避免在布尔条件语句中调用函数。 分配到局部变量并检查它们。

您调用了一个函数,并且基本上“丢弃”了结果以供以后使用。 如果稍后需要该信息,则必须再次调用该函数或者必须重写代码的结构。 它还会使检查或记录结果(以便将来的调试)变得更加困难。

请享用,

Robert C. Cartaino

关于1.13(避免使用完全限定的类型名称。请改用“using”语句):

它可能比可读性更强一些。 如果在文件开头有太多的使用,那么你有一个类与来自太多命名空间的类相结合。

这堂课正在为重构而尖叫。 使用using而不是完全限定的类名可以更轻松地识别这种紧密耦合的类。

这是我对你列出的问题的最好的准备。 对于那些我不能说的,我省略了。

1.13避免使用完全限定的类型名称。 请改用“using”语句。

可读性。 当您必须读取完全限定的类型名称时,必须更难读取代码。

2.19避免定义自定义exception类

.NET框架附带了一系列内置于系统中的exception。 除非您建模的exception是特定于业务领域的,否则您可能可以使用现有的exception类之一。

2.29避免使用三元条件运算符

我认为这很可能是因为他认为人们可能不了解运营商,但我不同意。

2.47避免与一个成员的接口。

他可能会警告人们构建太薄的接口。 但是,我实际上会说反过来,警告人们使界面过于冗长。 如果您曾经不得不处理ASP.NET MembershipProvider,那么您就知道我在说什么。

2.31避免在布尔条件语句中调用函数。 分配到局部变量并检查它们。

我能想到的几个原因在这里。 可读性。 如果你在其中进行函数调用,它可能使条件语句难以理解。 此外,如果你不看,它更难调试。

2.53首选使用显式接口实现

我相信他的推理是为了简洁起见。 但是,我实际上并不同意这种评估。 我认为Jon是正确的,当你可以使用隐式接口时,并在适当的时候使用。

以下是我敢回答的一些反应:)

1.13避免使用完全限定的类型名称。 请改用“using”语句。 我不同意。 这肯定与性能无关。 它可以提高var foo = new Foo()可读性,而不是var foo = new MyCompany.MyNamespace.Helpers.Xml.Foo()var foo = new MyCompany.MyNamespace.Helpers.Xml.Foo() – 没有。

2.19避免定义自定义exception类这是无意义的imho。 您应该避免创建从ApplicationException派生的自定义exception,但自定义exception没有任何问题(只要您不打算重新发明现有的exception)。

2.29避免使用三元条件运算符我不知道为什么它会成为指南。 我已经读过,并非所有人都使用它并且可能无法识别它,但这不是不使用有用运算符的正当理由。

2.31避免在布尔条件语句中调用函数。 分配到局部变量并检查它们。 在我看来,这只是一个可读性问题。

2.47避免与一个成员的接口。 我在这里也不同意。 你应该避免使用’marker’接口 – 没有标记的接口,但只是为了某些东西是’…… ble’的目的。 但是,界面上的一种方法对我来说似乎很好。

2.29三元运算符

首先,如果你开始使用三元运算符,那么应该有一个理由将三元运算符用于常规的if-then-else。 观察:

 if (x == 0) {...} else{...} //A set of statements demand a regular If-then-else //A simple assignment can be handled by the ternary operator y = (x == 0)? 1 : 0 //this is readable and how it should be used (x==0)? callSomething() : callSomethingElse() //this is NOT how it should be used 

三元语句用于根据其评估的条件返回两个值中的一个。 这在进行FP时非常方便。 对于不返回值的调用语句,您应该还原为if-then-else。