读 《CSharp Coding Guidelines》有感

目录


C# 编制程序指南

新近在 Github
上看见了壹位民代表大会牌创设四个储藏室:CSharpCodingGuidelines,张开之后看了须臾间
readme.md 相关描述,感到应该很不错,于是就 clone
到本地拜读一下,这里列一些谐和的笔记,方便日后回首。

基本原则

  • Astonishment
    原则:你的代码应该尽大概做到让每1位都能明了。任何人都有写出让机器认识的代码,不过并不是各类人都能写出让人认知的代码;
  • Kiss 原则:类似 Python 之禅 里面说的那么,轻松胜于复杂;
  • YAGNI
    原则:代码尽量能产生可扩展,但请不要过分重构,因为你不能预见今后;
  • D哈弗Y 原则:不要再度造轮子,除非你有时间依然您造的车轱辘会比人家的出色;
  • 面向对象编制程序原则:承袭、封装、多态、抽象;

类设计指南

  • 贰个类/接口应该唯有2个用途,要符 合单1职责 原则;
  • 只开创再次来到有用对象的构造函数,当构造函数的参数超过 3的话,你就应有思虑你的类设计是还是不是过分臃肿;
  • 接口应该短小精悍,其定义要鲜明清晰地传达出其颇具的作为;
  • 固然1种表现存各个贯彻,请思量动用接口而不是基类;
  • 尽量利用接口将类实行交互解耦;
  • 防止使用静态类;
  • 决不选用 new 关键字来禁止编写翻译器展现相关警告;

public class Book
{
    public virtual void Print()
    {
        Console.WriteLine("Printing Book");
    }
}

public class PocketBook : Book
{
    public new void Print()
    {
        Console.WriteLine("Printing PocketBook");
    }
}

class Program
{
    static void Main(string[] args)
    {
        PocketBook pocketBook = new PocketBook();
        pocketBook.Print();

        ((Book)pocketBook).Print();

        Console.ReadKey();
    }
}

在上述代码段中,大家创制一个基类 book,并定义了2个 Print()
方法,接着大家创造3个子类 PocketBook,并通过 new
关键字来重写基类方法。在品种复杂的状态下,使用那种艺术将产生我们不能够确切预测是子类调用照旧父类调用,使代码复杂度升高。

  • 有道是能够将派生类当作基类对象来拍卖;
  • 永不引用基类的派生类;
  • 制止揭发2个对象依赖的此外对象;
  • 制止双向注重;
  • 类应该有情形和行为;
  • 类应该保险其里面景观的一致性;

特性成员安顿指南

  • 同意按私下顺序设置属性;
  • 应用格局而不是性质;
  • 永不选拔相互排斥的属性;
  • 属性、方法只怕地方方法只应该做一件事情;
  • 毫无通过静态成员公开有情形的靶子;
  • 用 IEnumerable 大概 ICollection 来代表具体的聚合对象作为重回值;
  • 假定属性、参数和重返值是字符串可能聚众类型的话,则永久不该为空;
  • 全力以赴地定义具体的参数;
  • 设想动用特定域的值类型而不是基元;

另外安顿指南

  • 抛出尤其而不是回去某连串型的图景值;
  • 提供完整而有意义的卓殊音讯;
  • 抛出确切的最实际的卓殊;
  • 并非通过 try – catch 情势隐藏格外;
  • 正确管理异步代码中的相当;
  • 调用事件委托前先推断是或不是为空;

event EventHandler<string> Notify;
protected virtual void OnNotify(string args)
{
    Notify?.Invoke(this, args);
}
  • 应用受有限支撑的虚方法来触发各类事件;
  • 思量增加属性别变化化事件;
  • 当接触事件时要确定保证 sender != nulll;
  • 假如方便的话,请缅想选拔泛型约束;

class SomeClass
{
}

/// <summary>
/// 不推荐
/// </summary>
class MyClass1
{
    void SomeMethod<T>(T t)
    {
        object temp = t;
        SomeClass obj = (SomeClass)temp;
    }
}

/// <summary>
/// 推荐
/// </summary>
class MyClass2
{
    void SomeMethod<T>(T t) where T :SomeClass
    {
        SomeClass obj = t;
    }
}
  • 在回到 LINQ 表明式在此以前总括它的结果;
  • 例如不是必须,不要采取 thisbase 关键字;

可维护性指南

  • 办法内部的代码段尽量不要赶上 七 行;
  • 担保全数成员个人,类的类型默以为为 internal sealed
  • 幸免双重规范;
  • 在其蕴藉的命名空间内命名程序集;
  • 将源文件命名叫它所富含的种类;
  • 将源文件的内容限制为一种档期的顺序;
  • 将不一致的逻辑函数放到同叁个局地类中;
  • 在运用二个项目时,使用 using
    关键字导入要求的命名空间,而不是种类的全部空间标记;
  • 决不选用法力数;
  • 唯有当类型由此可见时才使用 var 关键字;
  • 概念变量时尽或然地起初化;
  • 在互相独立的代码段中定义一时变量;
  • 若对象有集聚须要开始化的话在开始展览对象起头化的还要开始展览联谊开头化;
  • 不用显式进行 bool 值的可比;
  • 防止嵌套循环;
  • 在使用
    ifelsedowhileforforeachcase
    的同时利用 {}
  • switch case 代码段中加多 default 逻辑;
  • 在具备的 ifelse if 后再加多 else;
  • 避免使用五个再次来到值;
  • 考虑采取简便的规范语句替代 if else
  • 封装属性、方法或一些函数中的复杂表明式;
  • 再贴切的情形下品尝重载方法;
  • 运用可选参数来代表重载;
  • 幸免使用命名参数;
  • 制止定义超越2个参数的签名;
  • 防止函数签名字为布尔类型;
  • 毫不将参数作为目前变量使用;
  • 将格局作为操作;
  • 不要讲明代码;

取名指南

  • 并非在变量、参数和连串成员中富含数字;
  • 决不在字段增多前缀;
  • 永不选择缩写;
  • 成员、参数和变量定义要依附它们代表的意思;
  • 使用名词、名词短语可能形容词来定义类型;
  • 选取描述性名称命名泛型参数;
  • 在类成员中不要再一次定义和类同样的称呼;
  • 成员定义可参照 .Net Framework 的概念方式;
  • 幸免使用大概被误会的段名称或字段;
  • 正确定义属性;
  • 在命名格局或一些函数时选择谓词或谓词对象;
  • 选择名称、层、谓词和成效申明命名空间;
  • 行使动词或动词前缀来定义事件;
  • 使用 ingend 后缀来声明事件预管理和发送事件;
  • 使用 on 前缀来定义事件管理程序;
  • 使用 Async 或者 TaskAsync 来标志异步方法;

品质指南

  • 使用 Any() 判断 IEnumerable 是不是为空 ;
  • 仅对低密集型活动选拔异步;
  • 对于 CPU密集型使用 Task.Run
  • 制止同时将 async/awaitTask.Wait 混合使用;
  • 避免 async/await 在单线程景况下出现死锁;

框架指南

  • 使用 C# 类型 小名而不是系量进行显式调用;
  • 绝不硬编码;统命名空间中的类型;
  • 利用最高警戒等级编写翻译代码;
  • 对于简易的表明式幸免使用 LINQ
  • 动用 lambda 表达式来顶替佚名函数;
  • 只用在应用动态指标时才使用 dynamic 关键字;
  • 支撑异步/等待任务接二连三;

文书档案指南

  • 选拔美式马耳他语来编排相关文书档案;
  • 文书档案中的代码部分要确定保障完整性;
  • 与其余开采职员一同编写 xml 文书档案;
  • 编写制定 MSDN 风格的手艺术文化书档案;
  • 防止内联注释;
  • 注释值应该用来讲明复杂的算法或商讨;
  • 不用使用注释来跟踪要在之后产生的劳作;

布局指南

  • 应用正规布局;
  • 听别人说公式须求实行命名空间的封锁;
  • 将成员置于定义突出的逐条中;
  • 严厉使用 #region
  • 适用使用表现完美的积极分子;

相关链接

相关文章