编程论坛
400万+工程师在用
华为|鸿蒙开发者日
直播报名
400万+工程师在用
华为|鸿蒙开发者日
直播报名

电子发烧友网工程师

17年用户 16436经验值
擅长:可编程逻辑 MEMS/传感技术 测量仪表 模拟技术 控制/MCU RF/无线
私信 关注

C#编码标准

2008-12-26 12:24

<p><font face="Verdana">C#编码标准--编码习惯&nbsp;&nbsp;&nbsp;<br/>1.&nbsp; 避免将多个类放在一个文件里面。 </font></p>
<p><font face="Verdana">2.&nbsp; 一个文件应该只有一个命名空间,避免将多个命名空间放在同一个文件里面。</font></p>
<p><font face="Verdana">3.&nbsp; 一个文件最好不要超过500行的代码(不包括机器产生的代码)。</font></p>
<p><font face="Verdana">4.&nbsp; 一个方法的代码长度最好不要超过25行。</font></p>
<p><font face="Verdana">5.&nbsp; 避免方法中有超过5个参数的情况。使用结构来传递多个参数。</font></p>
<p><font face="Verdana">6.&nbsp; 每行代码不要超过80个字符。</font></p>
<p><font face="Verdana">7.&nbsp; 不要手工的修改机器产生的代码。</font></p>
<p><font face="Verdana">a)&nbsp; 如果需要编辑机器产生的代码,编辑格式和风格要符合该编码标准。</font></p>
<p><font face="Verdana">b)&nbsp; Use partial classes whenever possible to factor out the maintained portions. </font></p>
<p><font face="Verdana">8.&nbsp; 避免利用注释解释显而易见的代码。</font></p>
<p><font face="Verdana">a)&nbsp; 代码应该可以自解释。好的代码由可读的变量和方法命名因此不需要注释。</font></p>
<p><font face="Verdana">9.&nbsp; Document only operational assumptions, algorithm insights and so on.&nbsp;&nbsp; </font></p>
<p><font face="Verdana">10.&nbsp; 避免使用方法级的文档。</font></p>
<p><font face="Verdana">a)&nbsp; 使用扩展的API文档说明之。</font></p>
<p><font face="Verdana">b)&nbsp; 只有在该方法需要被其他的开发者使用的时候才使用方法级的注释。(在C#中就是///)</font></p>
<p><font face="Verdana">11.&nbsp; 不要硬编码数字的值,总是使用构造函数设定其值。</font></p>
<p><font face="Verdana">12.&nbsp; 只有是自然结构才能直接使用const,比如一个星期的天数。</font></p>
<p><font face="Verdana">13.&nbsp; 避免在只读的变量上使用const。如果想实现只读,可以直接使用readonly。</font></p>
<p><font face="Verdana">public class MyClass </font></p>
<p><font face="Verdana">{ </font></p>
<p><font face="Verdana">&nbsp;&nbsp; public readonly int Number; </font></p>
<p><font face="Verdana">&nbsp;&nbsp; public MyClass(int&nbsp; someValue) </font></p>
<p><font face="Verdana">&nbsp;&nbsp; { </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number = someValue; </font></p>
<p><font face="Verdana">&nbsp;&nbsp; } </font></p>
<p><font face="Verdana">&nbsp;&nbsp; public&nbsp; const int&nbsp; DaysInWeek = 7; </font></p>
<p><font face="Verdana">} </font></p>
<p><font face="Verdana">14.&nbsp; 每个假设必须使用Assert检查</font></p>
<p><font face="Verdana">a)&nbsp; 平均每15行要有一次检查(Assert)</font></p>
<p><font face="Verdana">using System.Diagnostics; </font></p>
<p><font face="Verdana">&nbsp;</font></p>
<p><font face="Verdana">object GetObject() </font></p>
<p><font face="Verdana">{…} </font></p>
<p><font face="Verdana">&nbsp;</font></p>
<p><font face="Verdana">object obj = GetObject(); </font></p>
<p><font face="Verdana">debug.Assert(obj != null); </font></p>
<p><font face="Verdana">15.&nbsp; 代码的每一行都应该通过白盒方式的测试。</font></p>
<p><font face="Verdana">16.&nbsp; 只抛出已经显示处理的异常。</font></p>
<p><font face="Verdana">17.&nbsp; 在捕获(catch)语句的抛出异常子句中(throw),总是抛出原始异常维护原始错误的堆栈分配。</font></p>
<p><font face="Verdana">catch(Exception exception) </font></p>
<p><font face="Verdana">{&nbsp;&nbsp;&nbsp; </font></p>
<p><font face="Verdana">&nbsp;&nbsp; MessageBox.Show(exception.Message); </font></p>
<p><font face="Verdana">&nbsp;&nbsp; throw ;&nbsp; //和throw exception一样。 </font></p>
<p><font face="Verdana">} </font></p>
<p><font face="Verdana">18.&nbsp; 避免方法的返回值是错误代码。</font></p>
<p><font face="Verdana">19.&nbsp; 尽量避免定义自定义异常类。</font></p>
<p><font face="Verdana">20.&nbsp; 当需要定义自定义的异常时:</font></p>
<p><font face="Verdana">a)&nbsp; 自定义异常要继承于ApplicationException。</font></p>
<p><font face="Verdana">b)&nbsp; 提供自定义的序列化功能。</font></p>
<p><font face="Verdana">21.&nbsp; 避免在单个程序集里使用多个Main方法。</font></p>
<p><font face="Verdana">22.&nbsp; 只对外公布必要的操作,其他的则为internal。</font></p>
<p><font face="Verdana">23.&nbsp; Avoid friend assemblies, as it increases inter-assembly coupling.</font></p>
<p><font face="Verdana">24.&nbsp; Avoid code that relies on an assembly running from a particular location. </font></p>
<p><font face="Verdana">25.&nbsp; 使应用程序集尽量为最小化代码(EXE客户程序)。使用类库来替换包含的商务逻辑。</font></p>
<p><font face="Verdana">26.&nbsp; 避免给枚举变量提供显式的值。</font></p>
<p><font face="Verdana">//正确方法&nbsp; </font></p>
<p><font face="Verdana">public enum Color </font></p>
<p><font face="Verdana">{&nbsp;&nbsp;&nbsp; </font></p>
<p><font face="Verdana">&nbsp;&nbsp; Red,Green,Blue </font></p>
<p><font face="Verdana">} </font></p>
<p><font face="Verdana">//避免</font></p>
<p><font face="Verdana">public enum Color </font></p>
<p><font face="Verdana">{&nbsp;&nbsp;&nbsp; </font></p>
<p><font face="Verdana">&nbsp;&nbsp; Red = 1,Green =&nbsp; 2,Blue = 3 </font></p>
<p><font face="Verdana">} </font></p>
<p><font face="Verdana">27.&nbsp; 避免指定特殊类型的枚举变量。</font></p>
<p><font face="Verdana">//避免&nbsp; </font></p>
<p><font face="Verdana">public enum Color&nbsp; : long </font></p>
<p><font face="Verdana">{&nbsp;&nbsp;&nbsp; </font></p>
<p><font face="Verdana">&nbsp;&nbsp; Red,Green,Blue </font></p>
<p><font face="Verdana">} </font></p>
<p><font face="Verdana">28.&nbsp; 即使IF语句只有一句,也要将if语句的内容用大括号扩起来。</font></p>
<p><font face="Verdana">29.&nbsp; 避免使用trinary条件操作符。</font></p>
<p><font face="Verdana">30.&nbsp; 避免在条件语句中调用返回bool值的函数。可以使用局部变量并检查这些局部变量。</font></p>
<p><font face="Verdana">bool IsEverythingOK() </font></p>
<p><font face="Verdana">{…} </font></p>
<p><font face="Verdana">//避免 </font></p>
<p><font face="Verdana">if (IsEverythingOK ()) </font></p>
<p><font face="Verdana">{…} </font></p>
<p><font face="Verdana">//替换方案&nbsp; </font></p>
<p><font face="Verdana">bool ok = IsEverythingOK(); </font></p>
<p><font face="Verdana">if (ok) </font></p>
<p><font face="Verdana">{…} </font></p>
<p><font face="Verdana">31.&nbsp; 总是使用基于0开始的数组。</font></p>
<p><font face="Verdana">32.&nbsp; 在循环中总是显式的初始化引用类型的数组。</font></p>
<p><font face="Verdana">public class MyClass </font></p>
<p><font face="Verdana">{} </font></p>
<p><font face="Verdana">MyClass[] array = new&nbsp; MyClass[100]; </font></p>
<p><font face="Verdana">for(int index = 0; index &lt; array.Length;&nbsp; index++) </font></p>
<p><font face="Verdana">{ </font></p>
<p><font face="Verdana">&nbsp;&nbsp; array[index] = new&nbsp; MyClass(); </font></p>
<p><font face="Verdana">} </font></p>
<p><font face="Verdana">33.&nbsp; 不要提供public 和 protected的成员变量,使用属性代替他们。</font></p>
<p><font face="Verdana">34.&nbsp; 避免在继承中使用new而使用override替换。</font></p>
<p><font face="Verdana">35.&nbsp; 在不是seaLED的类中总是将public 和 protected的方法标记成virtual的。</font></p>
<p><font face="Verdana">36.&nbsp; 除非使用interop(COM+ 或其他的dll)代码否则不要使用不安全的代码(unsafe code)。</font></p>
<p><font face="Verdana">37.&nbsp; 避免显示的转换,使用as操作符进行兼容类型的转换。</font></p>
<p><font face="Verdana">Dog dog = new GermanShepherd(); </font></p>
<p><font face="Verdana">GermanShepherd shepherd = dog&nbsp; as&nbsp; GermanShepherd; </font></p>
<p><font face="Verdana">if (shepherd != null ) </font></p>
<p><font face="Verdana">{…} </font></p>
<p><font face="Verdana">38.&nbsp; 当类成员包括委托的时候</font></p>
<p><font face="Verdana">a)&nbsp; Copy a delegate to a local variable before publishing to avoid concurrency race </font></p>
<p><font face="Verdana">condition.&nbsp; </font></p>
<p><font face="Verdana">b)&nbsp; 在调用委托之前一定要检查它是否为null</font></p>
<p><font face="Verdana">public class MySource </font></p>
<p><font face="Verdana">{ </font></p>
<p><font face="Verdana">&nbsp;&nbsp; public event EventHandler&nbsp; MyEvent; </font></p>
<p><font face="Verdana">&nbsp;&nbsp; public void FireEvent() </font></p>
<p><font face="Verdana">&nbsp;&nbsp; { </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EventHandler temp = MyEvent; </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(temp != null ) </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp(this,EventArgs.Empty); </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </font></p>
<p><font face="Verdana">&nbsp;&nbsp; } </font></p>
<p><font face="Verdana">}&nbsp;&nbsp; </font></p>
<p><font face="Verdana">39.&nbsp; 不要提供公共的事件成员变量,使用事件访问器替换这些变量。</font></p>
<p><font face="Verdana">public class MySource </font></p>
<p><font face="Verdana">{ </font></p>
<p><font face="Verdana">&nbsp;&nbsp; MyDelegate m_SomeEvent ; </font></p>
<p><font face="Verdana">&nbsp;&nbsp; public event MyDelegate SomeEvent </font></p>
<p><font face="Verdana">&nbsp;&nbsp; { </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_SomeEvent += value; </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; remove </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_SomeEvent -= value; </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </font></p>
<p><font face="Verdana">&nbsp;&nbsp; } </font></p>
<p><font face="Verdana">} </font></p>
<p><font face="Verdana">40.&nbsp; 使用一个事件帮助类来公布事件的定义。 </font></p>
<p><font face="Verdana">41.&nbsp; 总是使用接口。</font></p>
<p><font face="Verdana">42.&nbsp; 类和接口中的方法和属性至少为2:1的比例。</font></p>
<p><font face="Verdana">43.&nbsp; 避免一个接口中只有一个成员。</font></p>
<p><font face="Verdana">44.&nbsp; 尽量使每个接口中包含3-5个成员。</font></p>
<p><font face="Verdana">45.&nbsp; 接口中的成员不应该超过20个。</font></p>
<p><font face="Verdana">a)&nbsp; 实际情况可能限制为12个 </font></p>
<p><font face="Verdana">46.&nbsp; 避免接口成员中包含事件。</font></p>
<p><font face="Verdana">47.&nbsp; 避免使用抽象方法而使用接口替换。</font></p>
<p><font face="Verdana">48.&nbsp; 在类层次中显示接口。</font></p>
<p><font face="Verdana">49.&nbsp; 推荐使用显式的接口实现。</font></p>
<p><font face="Verdana">50.&nbsp; 从不假设一个类型兼容一个接口。Defensively query for that inteRFace.</font></p>
<p><font face="Verdana">SomeType obj1; </font></p>
<p><font face="Verdana">IMyInterface obj2; </font></p>
<p><font face="Verdana">&nbsp; </font></p>
<p><font face="Verdana">/* 假设已有代码初始化过obj1,接下来 */ </font></p>
<p><font face="Verdana">obj2 = obj1 as IMyInterface; </font></p>
<p><font face="Verdana">if (obj2 != null) </font></p>
<p><font face="Verdana">{ </font></p>
<p><font face="Verdana">&nbsp;&nbsp; obj2.Method1(); </font></p>
<p><font face="Verdana">} </font></p>
<p><font face="Verdana">else </font></p>
<p><font face="Verdana">{ </font></p>
<p><font face="Verdana">&nbsp;&nbsp; //处理错误 </font></p>
<p><font face="Verdana">}&nbsp;&nbsp; </font></p>
<p><font face="Verdana">51.&nbsp; 表现给最终用户的字符串不要使用硬编码而要使用资源文件替换之。</font></p>
<p><font face="Verdana">52.&nbsp; 不要硬编码可能更改的基于配置的字符串,比如连接字符串。</font></p>
<p><font face="Verdana">53.&nbsp; 当需要构建长的字符串的时候,使用StringBuilder不要使用string</font></p>
<p><font face="Verdana">54.&nbsp; 避免在结构里面提供方法。</font></p>
<p><font face="Verdana">a)&nbsp; 建议使用参数化构造函数</font></p>
<p><font face="Verdana">b)&nbsp; 可以重裁操作符</font></p>
<p><font face="Verdana">55.&nbsp; 总是要给静态变量提供静态构造函数。</font></p>
<p><font face="Verdana">56.&nbsp; 能使用早期绑定就不要使用后期绑定。</font></p>
<p><font face="Verdana">57.&nbsp; 使用应用程序的日志和跟踪。</font></p>
<p><font face="Verdana">58.&nbsp; 除非在不完全的switch语句中否则不要使用goto语句。</font></p>
<p><font face="Verdana">59.&nbsp; 在switch语句中总是要有default子句来显示信息(Assert)。</font></p>
<p><font face="Verdana">int number&nbsp; = SomeMethod(); </font></p>
<p><font face="Verdana">switch(number) </font></p>
<p><font face="Verdana">{ </font></p>
<p><font face="Verdana">&nbsp;&nbsp; case 1: </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Trace.WriteLine("Case 1:"); </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break; </font></p>
<p><font face="Verdana">&nbsp;&nbsp; case 2: </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Trace.WriteLine("Case 2:"); </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break; </font></p>
<p><font face="Verdana">&nbsp;&nbsp; default : </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Debug.Assert(false); </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break; </font></p>
<p><font face="Verdana">} </font></p>
<p><font face="Verdana">60.&nbsp; 除非在构造函数中调用其他构造函数否则不要使用this指针。</font></p>
<p><font face="Verdana">// 正确使用this的例子 </font></p>
<p><font face="Verdana">public class MyClass </font></p>
<p><font face="Verdana">{ </font></p>
<p><font face="Verdana">&nbsp;&nbsp; public MyClass(string message ) </font></p>
<p><font face="Verdana">&nbsp;&nbsp; {} </font></p>
<p><font face="Verdana">&nbsp;&nbsp; public MyClass()&nbsp; : this("hello") </font></p>
<p><font face="Verdana">&nbsp;&nbsp; {} </font></p>
<p><font face="Verdana">} </font></p>
<p><font face="Verdana">61.&nbsp; 除非你想重写子类中存在名称冲突的成员或者调用基类的构造函数否则不要使用base来访问基类的成员。</font></p>
<p><font face="Verdana">// 正确使用base的例子</font></p>
<p><font face="Verdana">public class Dog </font></p>
<p><font face="Verdana">{ </font></p>
<p><font face="Verdana">&nbsp;&nbsp; public Dog(string name) </font></p>
<p><font face="Verdana">&nbsp;&nbsp; {} </font></p>
<p><font face="Verdana">&nbsp;&nbsp; virtual public void Bark( int howLong) </font></p>
<p><font face="Verdana">&nbsp;&nbsp; {} </font></p>
<p><font face="Verdana">} </font></p>
<p><font face="Verdana">public class GermanShepherd : Dog </font></p>
<p><font face="Verdana">{ </font></p>
<p><font face="Verdana">&nbsp;&nbsp; public GermanShe pherd(string name): base (name) </font></p>
<p><font face="Verdana">&nbsp;&nbsp; {} </font></p>
<p><font face="Verdana">&nbsp;&nbsp; override public void Bark(int&nbsp; howLong)&nbsp; </font></p>
<p><font face="Verdana">&nbsp;&nbsp; { </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; base .Bark(howLong);&nbsp;&nbsp; </font></p>
<p><font face="Verdana">&nbsp;&nbsp; } </font></p>
<p><font face="Verdana">} </font></p>
<p><font face="Verdana">62.&nbsp; 基于模板的时候要实现Dispose()和Finalize()两个方法。</font></p>
<p><font face="Verdana">63.&nbsp; 通常情况下避免有从System.Object转换来和由System.Object转换去的代码,而使用强制转换或者as操作符替换。</font></p>
<p><font face="Verdana">class SomeClass </font></p>
<p><font face="Verdana">{} </font></p>
<p><font face="Verdana">//避免: </font></p>
<p><font face="Verdana">class MyClass&lt;T&gt;&nbsp; </font></p>
<p><font face="Verdana">{&nbsp;&nbsp;&nbsp; </font></p>
<p><font face="Verdana">&nbsp;&nbsp; void SomeMethod(T t)&nbsp;&nbsp;&nbsp; </font></p>
<p><font face="Verdana">&nbsp;&nbsp; { </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; object temp = t;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SomeClass obj = (SomeClass)temp;&nbsp;&nbsp;&nbsp;&nbsp; </font></p>
<p><font face="Verdana">&nbsp;&nbsp; } </font></p>
<p><font face="Verdana">} </font></p>
<p><font face="Verdana">// 正确: </font></p>
<p><font face="Verdana">class MyClass&lt;T&gt; where T : SomeClass </font></p>
<p><font face="Verdana">{&nbsp;&nbsp;&nbsp; </font></p>
<p><font face="Verdana">&nbsp;&nbsp; void SomeMethod(T t)&nbsp;&nbsp;&nbsp; </font></p>
<p><font face="Verdana">&nbsp;&nbsp; { </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SomeClass obj = t;&nbsp;&nbsp;&nbsp; </font></p>
<p><font face="Verdana">&nbsp;&nbsp; } </font></p>
<p><font face="Verdana">} </font></p>
<p><font face="Verdana">64.&nbsp; 在一般情况下不要定影有限制符的接口。接口的限制级别通常可以用强类型来替换之。<br/>public class Customer </font></p>
<p><font face="Verdana">{…} </font></p>
<p><font face="Verdana">//避免:</font></p>
<p><font face="Verdana">public interface IList&lt;T&gt; where T : Customer&nbsp; </font></p>
<p><font face="Verdana">{…} </font></p>
<p><font face="Verdana">//正确:</font></p>
<p><font face="Verdana">public interface ICustomerList : IList&lt;Customer&gt;&nbsp; </font></p>
<p><font face="Verdana">{…} </font></p>
<p><font face="Verdana">65.&nbsp; 不确定在接口内的具体方法的限制条件。</font></p>
<p><font face="Verdana">66.&nbsp; 总是选择使用C#内置(一般的generics)的数据结构。 </font></p>
<p><font face="Verdana">&nbsp;</font></p>
<p><font face="Verdana">&nbsp;</font></p>
<p><font face="Verdana">由于本人水平有限,如果在翻译中有什么错误我将本着疯狂英语的态度,随便说好了,但是一定要给出我合适的理由,谢谢让我丢脸。另外文章中有几处没有翻译,那是我实在翻不出来,我将原文放在那里希望高手指点!谢谢!<br/></font></p>

回帖(1)

葛平鑫

2012-6-27 19:06:52
好复杂啊!

更多回帖

打开APP