C# 编程指南

前不久在 Github 上看见了一位大牛创建一个仓库:CSharpCodingGuidelines,打开之后看了一下 readme.md 相关描述,感觉应该很不错,于是就 clone 到本地拜读一下,这里列一些自己的笔记,方便日后回顾。

基本原则

  • Astonishment 原则:你的代码应该尽量做到让每一个人都能理解。任何人都有写出让机器认识的代码,但是并不是每个人都能写出让人认识的代码;
  • Kiss 原则:类似 Python 之禅 里面说的那样,简单胜于复杂;
  • YAGNI 原则:代码尽量能做到可扩展,但请不要过度重构,因为你不能预知未来;
  • DRY 原则:不要重复造轮子,除非你有时间或者你造的轮子会比别人的优秀;
  • 面向对象编程原则:继承、封装、多态、抽象;

类设计指南

  • 一个类/接口应该只有一个用途,要符 合单一职责 原则;
  • 只创建返回有用对象的构造函数,当构造函数的参数超过 3 的话,你就应该考虑你的类设计是否过于臃肿;
  • 接口应该短小精悍,其定义要明确清晰地传达出其具有的行为;
  • 如果一种行为有多种实现,请考虑使用接口而不是基类;
  • 尽量使用接口将类进行彼此解耦;
  • 避免使用静态类;
  • 不要使用 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,并定义了一个 Print() 方法,接着我们创建一个子类 PocketBook,并通过 new 关键字来重写基类方法。在项目复杂的情况下,使用这种方式将导致我们不能准确预测是子类调用还是父类调用,使代码复杂度提升。

  • 应该可以将派生类当作基类对象来处理;
  • 不要引用基类的派生类;
  • 避免暴露一个对象依赖的其它对象;
  • 避免双向依赖;
  • 类应该有状态和行为;
  • 类应该保护其内部状态的一致性;

属性成员设计指南

  • 允许按任意顺序设置属性;
  • 使用方法而不是属性;
  • 不要使用相互排斥的属性;
  • 属性、方法或者本地方法只应该做一件事情;
  • 不要通过静态成员公开有状态的对象;
  • 用 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 关键字;

可维护性指南

  • 方法内部的代码段尽量不要超过 7 行;
  • 确保所有成员私有,类的类型默认为为 internal sealed
  • 避免双重条件;
  • 在其包含的命名空间内命名程序集;
  • 将源文件命名为它所包含的类型;
  • 将源文件的内容限制为一种类型;
  • 将不同的逻辑函数放到同一个部分类中;
  • 在使用一个类型时,使用 using 关键字导入需要的命名空间,而不是类型的完整空间标识;
  • 不要使用魔法数;
  • 只有当类型显而易见时才使用 var 关键字;
  • 定义变量时尽可能地初始化;
  • 在相互独立的代码段中定义临时变量;
  • 若对象有集合需要初始化的话在进行对象初始化的同时进行集合初始化;
  • 不要显式进行 bool 值的比较;
  • 避免嵌套循环;
  • 在使用 ifelsedowhileforforeachcase 的同时使用 {}
  • switch case 代码段中添加 default 逻辑;
  • 在所有的 ifelse if 后再添加 else;
  • 避免使用多个返回值;
  • 考虑使用简单的条件语句代替 if else
  • 封装属性、方法或局部函数中的复杂表达式;
  • 再合适的情况下尝试重载方法;
  • 使用可选参数来代替重载;
  • 避免使用命名参数;
  • 避免定义超过3个参数的签名;
  • 避免函数签名为布尔类型;
  • 不要将参数作为临时变量使用;
  • 将模式作为操作;
  • 不要注释代码;

命名指南

  • 不要在变量、参数和类型成员中包含数字;
  • 不要在字段添加前缀;
  • 不要使用缩写;
  • 成员、参数和变量定义要根据它们代表的意义;
  • 使用名词、名词短语或者形容词来定义类型;
  • 使用描述性名称命名泛型参数;
  • 在类成员中不要重复定义和类相同的名称;
  • 成员定义可参考 .Net Framework 的定义方式;
  • 避免使用可能被误解的段名称或字段;
  • 正确定义属性;
  • 在命名方法或局部函数时使用谓词或谓词对象;
  • 使用名称、层、谓词和功能申明命名空间;
  • 使用动词或动词前缀来定义事件;
  • 使用 ingend 后缀来表达事件预处理和发送事件;
  • 使用 on 前缀来定义事件处理程序;
  • 使用 Async 或者 TaskAsync 来标识异步方法;

性能指南

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

框架指南

  • 使用 C# 类型 别名而不是系量进行显式调用;
  • 不要硬编码;统命名空间中的类型;
  • 使用最高警告级别编译代码;
  • 对于简单的表达式避免使用 LINQ
  • 使用 lambda 表达式来代替匿名函数;
  • 只用在使用动态对象时才使用 dynamic 关键字;
  • 支持异步/等待任务延续;

文档指南

  • 使用美式英语来编写相关文档;
  • 文档中的代码部分要保证完整性;
  • 与其他开发人员一起编写 xml 文档;
  • 编写 MSDN 风格的技术文档;
  • 避免内联注释;
  • 注释值应该用来解释复杂的算法或讨论;
  • 不要使用注释来跟踪要在以后完成的工作;

布局指南

  • 使用常规布局;
  • 根据公式要求进行命名空间的约束;
  • 将成员置于定义良好的顺序中;
  • 谨慎使用 #region
  • 适当使用表现健全的成员;

相关链接

读 《CSharp Coding Guidelines》有感的更多相关文章

  1. 读javascript高级程序设计00-目录

    javascript高级编程读书笔记系列,也是本砖头书.感觉js是一种很好上手的语言,不过本书细细读来发现了很多之前不了解的细节,受益良多.<br/>本笔记是为了方便日后查阅,仅作学习交流 ...

  2. 读javascript高级程序设计-目录

    javascript高级编程读书笔记系列,也是本砖头书.感觉js是一种很好上手的语言,不过本书细细读来发现了很多之前不了解的细节,受益良多.<br/>本笔记是为了方便日后查阅,仅作学习交流 ...

  3. JavaScript: The Evil Parts - 1

    最近在看JavaScript框架设计,在讲解类型判定的时候提到了一些“匪夷所思的情况”,不过没有明说都是什么时候会出现这些情况.自己玩儿了一下,写写随笔吧.不过可能除了我找到的,还有会其他时候会出现这 ...

  4. 读 《JavaScript: The Good Parts》 有感

    提炼出一门语言或技术的 Good Parts, 使用该子集去构造健壮稳固的应用. 我们总是倾向于去学习和使用所有的语言特性,好像凡是新的,凡是提供了的, 就有必要去使用: 这本书告诉我们, 要有选择性 ...

  5. 读javascript高级程序设计17-在线检测,cookie,子cookie

    一.在线状态检测 开发离线应用时,往往在离线状态时把数据存在本地,而在联机状态时再把数据发送到服务器.html5提供了检测在线状态的方法:navigator.onLine和online/offline ...

  6. JavaScript: The Good Parts

    Chapter 1 Good Parts: JavaScript is an important language because it is the language of the web brow ...

  7. 读javascript高级程序设计01-基本概念、数据类型、函数

    一. javascript构成 1.javascript实现由三部分组成: ECMAScript:核心语言功能 DOM:文档对象模型,提供访问和操作网页内容的方法和接口 BOM:浏览器对象模型,提供与 ...

  8. 读javascript高级程序设计02-变量作用域

    一. 延长作用域链 有些语句可以在作用域前端临时增加一个变量对象,该变量对象在代码执行完成后会被移除. ①with语句延长作用域. function buildUrl(){ var qs=" ...

  9. 读javascript高级程序设计08-引用类型之Global、Math、String

    一.Global 所有在全局作用域定义的属性和方法,都属于Global对象. 1.URI编码: encodeURI():主要用于对整个URI编码.它不会对本身属于URI的特殊字符进行编码. encod ...

  10. 读javascript高级程序设计10-DOM

    一.节点关系 元素的childNodes属性来表示其所有子节点,它是一个NodeList对象,会随着DOM结构的变化动态变化. hasChildNodes():是否有子节点. var headline ...

随机推荐

  1. [opentwebst]一个简单的登陆脚本

    这个是个简单的vbs脚本,使用opentwebst进行录制 'Use the command line below to launch the script (or just double click ...

  2. MFS故障测试及维护总结

    一.测试环境说明: 10.2.2.230 mfsmaster     VIP:10.2.2.130 10.2.2.231 mfsbackup 10.2.2.253 mfsdata01 10.2.2.2 ...

  3. 736. Parse Lisp Expression

    You are given a string expression representing a Lisp-like expression to return the integer value of ...

  4. vue-cli脚手架项目按需引入elementUI

    https://www.jianshu.com/p/40da0ba35ac1 Couldn't find preset "es2015" relative to directory ...

  5. HashMap的源码分析

    hashMap的底层实现是 数组+链表 的数据结构,数组是一个Entry<K,V>[] 的键值对对象数组,在数组的每个索引上存储的是包含Entry的节点对象,每个Entry对象是一个单链表 ...

  6. liunx下判断有线网口硬件是否正常的三个常用方式

    第一种,命令法: /mnt/wifi$ cat /proc/net/dev Inter-|  Receive                                              ...

  7. 脚手架vue-cli系列五:基于Nightwatch的端到端测试环境

    不同公司和组织之间的测试效率迥异.在这个富交互和响应式处理随处可见的时代,很多组织都使用敏捷的方式来开发应用,因此测试自动化也成为软件项目的必备部分.测试自动化意味着使用软件工具来反复运行项目中的测试 ...

  8. web自动化测试---selenium分布式测试

    使用selenium框架还可以进行分布式测试,操作如下: 准备俩台PC:A和B,ip分别为IP_A和IP_B 下载最新的selenium-standalone的jar包,可以到下面地址下载各版本的包: ...

  9. Mybatis-generator生成Service和Controller

    好久记录笔记,这段时间做政府的项目,数据录入系统基本都是通过excel导入,且数据量大,许多也是单表的录入,这就有很多可以通用的代码,如controller,service层的那一套都是可以代码生成, ...

  10. 解决Chrome浏览器主页被hao123、360和2345篡改简单有效方法

    转自:https://blog.csdn.net/qq_32635971/article/details/72793115?locationNum=10&fps=1 当你打开浏览器看到各种首页 ...