【编码规范篇】 C#编码规范 代码规范总结,包括命名规范,代码规范 注释规范等_c(1)

1.classrecordrecord的参数struct的名称,如:

public class DataService
{
}

public record PhysicalAddress(
    string Street,
    string City,
    string StateOrProvince,
    string ZipCode);
    
public struct ValueCoordinate
{
}

2.命名 interface 时,使用 pascal 大小写并在名称前面加上前缀 I。 这可以清楚地向使用者表明这是 interface。

public interface IWorkerQueue
{
}

3.public的成员也应为Pascal命名,这些成员包括字段、属性、事件。
方法名也应遵循Pascal命名,无论其是否是public。如:

public class ExampleEvents
{
	//公共字段
	public bool IsValid;
	//公共属性
	public IWorkQueue WorkQueue{get;set;}
	//公共事件
	public event Action EventProcessing;
	//公共方法
	public void Run()
	{
	}
}

4.编写位置记录时,对参数使用 pascal 大小写,因为它们是记录的公共属性。

public record PhysicalAddress(
    string Street,
    string City,
    string StateOrProvince,
    string ZipCode);

2.2 驼峰命名法(camelCasing)

1.命名privateinternal字段时使用驼峰命名,且字段名应以_开头。如:

public class DataService
{
    private IWorkerQueue _workerQueue;
}

2.如果是staticprivateinternal的字段,则字段名应该以s_开头,对于线程静态则应该使用t_开头。如:

public class DataService
{
    private static IWorkerQueue s_workerQueue;

    [ThreadStatic]
    private static TimeSpan t_timeSpan;
}

3.编写方法的参数名时,也应该以驼峰命名,如:

public T SomeMethod<T>(int someNumber, bool isValid)
{
}

2.3 其他命名约定
  1. 在不包括 using 指令的示例中,使用命名空间限定。

如果你知道命名空间默认导入项目中,则不必完全限定来自该命名空间的名称。 如果对于单行来说过长,则可以在点 (.) 后中断限定名称,如下面的示例所示。

var currentPerformanceCounterCategory = new System.Diagnostics.
 PerformanceCounterCategory();

不必更改使用 Visual Studio 设计器工具创建的对象的名称以使它们适合其他准则。

  1. 代码中当且仅当私有成员可以使用下划线_开始
  2. 代码中的命名严禁使用拼音与英文混合的方式,更不能允许直接使用中文的方式。
  3. 常量命名全部大写,单词间用下划线隔开,力求语意表达完整清楚,不要嫌名字长。
正例:MAX_XIAOY_COUNT
反例:MAX_xiaoy_COUNT

  1. 抽象类 命名使用 Abstract或Base开头;异常类命名使用Exception结尾;测试类命名以它要测试的类名称开始,以Test结尾。
	/// <summary>
    /// 抽象类命名
    /// </summary>
	public void AbstractLearnProgramming()
    {
    }
	/// <summary>
    /// 异常类命名
    /// </summary>
	public void LearnProgrammingException()
	{
	}
	/// <summary>
    /// 测试类命名
    /// </summary>
	public void LearnProgrammingTest()
	{
	}

  1. 如果使用了设计模式,建议在类名中体现出具体模式。

说明:将设计模式体现在名字中,有利于阅读者快速理解架构设计思想。
例如:

  public class SysuserController
  public class OrderFactory
  public class TcpProxy

  1. 枚举 类名建议带上E前缀或Enum后缀,枚举成员名称需要全大写,单词间用下滑线隔开。

说明:枚举其实就是特殊的常量类i,切构造方法被默认强制是私有。
正例:枚举名字:EState / DealStatusEnum
成员名:SUCCESS / UNKOWN_REASON


三、布局规范

1.使用默认的代码编辑器设置(智能缩进、4 字符缩进、制表符保存为空格)。

2.每行只写一条语句。

    //正确
    int age = 20;
    int score = 90;

    //错误示范
    int age = 20; int score = 90;

3.每行只写一个声明。

4.C# 的大括号采用的是Allman style,大括号单独一行。以下是正确的:

    /// <summary>
    /// 正确示范
    /// </summary>
    public void StartGame()
    {
    }

    /// <summary>
    /// 错误示范
    /// </summary>
    public void StartGame(){
    }

5.如果连续行未自动缩进,请将它们缩进一个制表符位(四个空格)。

在这里插入图片描述

6.在方法定义与属性定义之间添加至少一个空白行。

    public string Name { get; set; }

    public void StartGame()
    {
    }

7.使用括号突出表达式中的子句,如下面的代码所示。

if ((val1 > val2) && (val1 > val3))
{
    // Take appropriate action.
}

8.if / for / while / switch / do 等保留字与左右括号之间都必须加空格。

9.任何运算符左右必须加一个空格。

说明:运算符包括赋值运算符 = 、逻辑运算符&&、加减乘除符号、三目运算符等。

10.方法参数在定义和传入时,多个参数逗号后必须加空格。
正例:下例中实参的 ” a ” ,后边必须要有一个空格。

XIaoYMethod("a", "b", "c");


四、注释规范

1.将注释放在单独的行上,而非代码行的末尾。

正确示范

    // 定义age并初始化. Define age and init.
    int age = 20;

错误示范

    int age = 20;//定义age并初始化

2.类方法的注释必须使用C# Summary 规范,以大写字母开始注释文本。

    /// <summary>
    /// Start the text with a capital letter.
    /// </summary>
    public void StartGame()
    {
    }

说明:在vs中,Summary方式会提示相关的注释,生成Summary可以正确输出相应的注释。工程调用方法是,不进入方法,即可悬浮提示方法、参数、返回值的意义,提高阅读效率。

3.以句点结束注释文本。

4.在注释分隔符 (//) 与注释文本之间插入一个空格,如下面的示例所示。

// The following declaration creates a query. It does not run
// the query.

5.请勿在注释周围创建格式化的星号块。

6.请确保所有公共成员Public都有必要的注释,从而提供有关其行为的适当说明。

7.所有的抽象方法(包括接口中的方法)必须使用Summary注释,除了返回值、参数、异常说明外,还必须指出该方法做了什么事,实现了什么功能。
说明:对于子类的实现要求,或者调用注意事项,请一并说明。

8.方法内部单行注释,在被注释语句上方另起一行,使用 // 注释。方法内部多行注释使用 /* */ 注释,注意与代码对齐。

9.语气 “ 半吊子 ” 英文来注释,不如用中文注释把问题说清楚。但专有名字与关键字保持英文原文即可。
反例: “ TCP连接超时 ” 解释成 “ 传输控制协议连接超时 ” ,理解反而费脑筋。

10.代码修改的同事,注释也要进行相应的修改,预期是参数、返回值、异常、核心逻辑等的修改。

11.注释掉的代码尽可能而配合说明,而不是简单的注释掉
说明:代码被注释掉有两种可能性:

  • 1)后续会恢复此段代码逻辑。
  • 2)永久不用。前者如果没有备注信息,难以知晓注释动机。后者建议直接删掉(代码仓库保存了历史代码)。

12.对于注释的要求:

  • 第一:能够准确反应设计思想和代码逻辑;
  • 第二:能够描述业务含义,使别的程序员能够迅速了解到代码背后的信息。

完全没有注释的大段代码,对于阅读者形同天书,注释是给自己看的,即使隔很长时间,也能够清晰理解当时的思路;
注释也是给继任者看的,使其能够快读接替自己的工作。

13.好的命名、代码结构是自解释的,注释力求精简准确,表达到位。
避免出现注释的一个极端:过多滥的注释,代码逻辑一旦修改,修改注释是相当大的负担。

14.特殊注释标记,请注明标记人与标记时间。
注意及时处理这些标记,通过标记扫描,经常清理此类标记。线上故障有时候就是来源于这些标记处的代码。
1)待办事宜(TODO):(标记人、标记时间,[预计处理时间])表示需要实现,但目前还未实现的功能。


五、代码规范/语言准则

5.1 字符串数据类型
  1. 使用字符串内插来连接短字符串,如下面的代码所示。
string displayName = $"{nameList[n].LastName}, {nameList[n].FirstName}";

  1. 若要在循环中追加字符串,尤其是在使用大量文本时,请使用 StringBuilder 对象。
var phrase = "xiaoYxiaoYxiaoYxiaoYxiaoYxiaoY";
var manyPhrases = new StringBuilder();
for (var i = 0; i < 10000; i++)
{
    manyPhrases.Append(phrase);
}
//Console.WriteLine("tra" + manyPhrases);

5.2 隐式类型本地变量
  1. 当变量类型明显来自赋值的右侧时,或者当精度类型不重要时,请对本地变量进行隐式类型化
var var1 = "This is clearly a string.";
var var2 = 27;

  1. 当类型并非明显来自赋值的右侧时,请勿使用 var。 请勿假设类型明显来自方法名称。 如果变量类型为 new 运算符或显式强制转换,则将其视为明显来自方法名称。
int var3 = Convert.ToInt32(Console.ReadLine()); 
int var4 = ExampleClass.ResultSoFar();

  1. 请勿依靠变量名称来指定变量的类型。 它可能不正确。 在以下示例中,变量名称 inputInt 会产生误导性。 它是字符串。
var inputInt = Console.ReadLine();
Console.WriteLine(inputInt);

  1. 使用隐式类型化来确定 for 循环中循环变量的类型。
    下面的示例在 for 语句中使用隐式类型化。
var phrase = "xiaoYxiaoYxiaoYxiaoYxiaoYxiaoY";
var manyPhrases = new StringBuilder();
for (var i = 0; i < 10000; i++)
{
    manyPhrases.Append(phrase);
}
//Console.WriteLine("tra" + manyPhrases);

  1. 不要使用隐式类型化来确定 foreach 循环中循环变量的类型。 在大多数情况下,集合中的元素类型并不明显。 不应仅依靠集合的名称来推断其元素的类型。

下面的示例在 foreach 语句中使用显式类型化。

foreach (char ch in laugh)
{
    if (ch == 'h')
        Console.Write("H");
    else
        Console.Write(ch);
}
Console.WriteLine();

5.3 无符号数据类型

通常,使用 int 而非无符号类型。 int 的使用在整个 C# 中都很常见,并且当你使用 int 时,更易于与其他库交互。

5.4 数组

当在声明行上初始化数组时,请使用简洁的语法。 在以下示例中,请注意不能使用 var 替代 string[]

string[] xiaoY = { "x", "i", "a", "o", "Y" };

如果使用显式实例化,则可以使用 var

var xiaoY = new string[] { "x", "i", "a", "o", "Y" };

5.5 委托

在用到委托时尽量使用 Func<>Action<>,而不是自定义委托类型。 在类中,定义委托方法。

	public static Action<string> ActionExample1 = x => Console.WriteLine($"x is: {x}");

	public static Action<string, string> ActionExample2 = (x, y) => 
    Console.WriteLine($"x is: {x}, y is {y}");
    
	public static Action<string> ActionExample3 = X;

	static void X(string s)
    {
		Console.WriteLine($"x is: {s}");
	}


	public static Func<string, int> FuncExample1 = x => Convert.ToInt32(x);

	public static Func<int, int, int> FuncExample2 = (x, y) => x + y;

如果创建委托类型的实例,请使用简洁的语法。 在类中,定义委托类型和具有匹配签名的方法。

public delegate void Del(string message);

public static void DelMethod(string str)
{
    Console.WriteLine("DelMethod argument: {0}", str);
}

创建委托类型的实例,然后调用该实例。 以下声明显示了紧缩的语法。

Del exampleDel2 = DelMethod;
exampleDel2("Hey xiaoY");

以下声明使用了完整的语法。

Del exampleDel1 = new Del(DelMethod);
exampleDel1("Hey xiaoY");

5.6 异常处理

1.try-catch 和 using 语句正在异常处理中
在平时使用异常处理时一般都使用 try-catch 语句。我们可以使用 using 来简化代码,简化资源的Dispose

如果具有 try-finally语句(该语句中 finally 块的唯一代码是对 Dispose 方法的调用),可使用 using 语句代替。

如:

Font font1 = new Font("Arial", 10.0f);
try
{
    byte charset = font1.GdiCharSet;
}
finally
{
    if (font1 != null)
    {
        ((IDisposable)font1).Dispose();
    }
}

可使用using简化为:

using (Font font2 = new Font("Arial", 10.0f))
{
    byte charset2 = font2.GdiCharSet;
}

在C# 8中可以进一步简化:

using Font font3 = new Font("Arial", 10.0f);
byte charset3 = font3.GdiCharSet;


2.异常不要用来做流程控制,条件控制。因为异常的处理效率比条件分支低。

3.大段代码进行try-catch,这是不负责任的表现。catch时请分清稳定代码合肥稳定代码,稳定代码指的是无论如何都不会出错的代码。对于费稳定代码的catch尽量可能的进行区分异常类型,再做对应的异常处理。

4.捕获异常是为了处理它,不要捕获了却什么都不处理而抛弃之,如果不想处理它,就将该异常抛给他的调用者。最外层的业务使用者,必须处理异常,将其转化为用户可以理解的内容。

5.有try块放到了事务代码中,catch异常后,如果要回滚事务,一定要注意手动回滚事务。

6.finally块必须对资源对象、流对象进行关闭,有异常也要做tyr-catch。

7.捕获异常与抛异常,必须是完全匹配,或者捕获异常是抛异常的父类。
说明:如果预期对方抛的是绣球,实际接到的是铅球,就会产生意外情况。

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

,稳定代码指的是无论如何都不会出错的代码。对于费稳定代码的catch尽量可能的进行区分异常类型,再做对应的异常处理。

4.捕获异常是为了处理它,不要捕获了却什么都不处理而抛弃之,如果不想处理它,就将该异常抛给他的调用者。最外层的业务使用者,必须处理异常,将其转化为用户可以理解的内容。

5.有try块放到了事务代码中,catch异常后,如果要回滚事务,一定要注意手动回滚事务。

6.finally块必须对资源对象、流对象进行关闭,有异常也要做tyr-catch。

7.捕获异常与抛异常,必须是完全匹配,或者捕获异常是抛异常的父类。
说明:如果预期对方抛的是绣球,实际接到的是铅球,就会产生意外情况。

[外链图片转存中…(img-b93r8dsY-1714177703051)]
[外链图片转存中…(img-dk7Cw1Vr-1714177703052)]
[外链图片转存中…(img-WuS7v8K6-1714177703052)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值