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。