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

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

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

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

如果你需要这些资料,可以添加V获取:vip204888 (备注大数据)
img

正文

/// </summary>
public void LearnProgrammingException()
{
}
/// <summary>
/// 测试类命名
/// </summary>
public void LearnProgrammingTest()
{
}

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


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



public class SysuserController
public class OrderFactory
public class TcpProxy


7. `枚举` 类名建议带上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.如果连续行未自动缩进,请将它们缩进一个制表符位(四个空格)。


![在这里插入图片描述](https://img-blog.csdnimg.cn/a38076480ae74978961a4c889f1df338.png)


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}”;


2. 若要在循环中追加字符串,尤其是在使用大量文本时,请使用 `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;


2. 当类型并非明显来自赋值的右侧时,请勿使用 `var`。 请勿假设类型明显来自方法名称。 如果变量类型为 new 运算符或显式强制转换,则将其视为明显来自方法名称。



int var3 = Convert.ToInt32(Console.ReadLine());
int var4 = ExampleClass.ResultSoFar();


3. 请勿依靠变量名称来指定变量的类型。 它可能不正确。 在以下示例中,变量名称 `inputInt` 会产生误导性。 它是字符串。



var inputInt = Console.ReadLine();
Console.WriteLine(inputInt);


4. 使用隐式类型化来确定 `for` 循环中循环变量的类型。  
 下面的示例在 for 语句中使用隐式类型化。



var phrase = “xiaoYxiaoYxiaoYxiaoYxiaoYxiaoY”;
var manyPhrases = new StringBuilder();
for (var i = 0; i < 10000; i++)
{
manyPhrases.Append(phrase);
}
//Console.WriteLine(“tra” + manyPhrases);


5. 不要使用隐式类型化来确定 `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.捕获异常与抛异常,必须是完全匹配,或者捕获异常是抛异常的父类。  
 说明:如果预期对方抛的是绣球,实际接到的是铅球,就会产生意外情况。


8.方法的返回值可以是null,不强制返回空集合或空对象等,必须添加注释充分说明什么情况下会返回null值。调用方进行null判断,防止NRE空引用异常问题(NullReferenceException)。


#### 5.7 && 和 || 运算符


若要通过跳过不必要的比较来避免异常并提高性能,请在执行比较时使用 `&&`(而不是 &)和  `||`(而不是 |),如下面的示例所示。



Console.Write("Enter a dividend: ");
int dividend = Convert.ToInt32(Console.ReadLine());

Console.Write("Enter a divisor: ");
int divisor = Convert.ToInt32(Console.ReadLine());

if ((divisor != 0) && (dividend / divisor > 0))
{
Console.WriteLine(“Quotient: {0}”, dividend / divisor);
}
else
{
Console.WriteLine(“Attempted division by 0 ends up here.”);
}


如果除数为 0,则 if 语句中的第二个子句将导致运行时错误。


但是,当第一个表达式为 false 时,`&&` 运算符将发生短路。 也就是说,它并不评估第二个表达式。 如果 divisor 为 0,则 `&` 运算符将同时计算这两个表达式,这会导致运行时错误。


#### 5.8 new 运算符 使用对象初始化值设定简化对象创建


使用对象初始值设定项简化对象创建,如以下示例中所示。



var student1 = new ExampleClass { Name = “xioaY”, ID = 001,
sex = “man”, Age = 24 };


下面的示例设置了与前面的示例相同的属性,但未使用初始值设定项。不建议使用



var student2 = new ExampleClass();
student2.Name = “xiaoYY”;
student2.ID = 002;
student2.sex = “man”;
student2.Age = 20;


#### 5.9 事件处理


如果正在定义一个稍后不需要删除的事件处理程序,请使用 `lambda` 表达式。



public Form1()
{
this.Click += (s, e) =>
{
MessageBox.Show(
((MouseEventArgs)e).Location.ToString());
};
}


`Lambda` 表达式缩短了以下传统定义。



public Form1()
{
this.Click += new EventHandler(Form1_Click);
}

void Form1_Click(object? sender, EventArgs e)
{
MessageBox.Show(((MouseEventArgs)e).Location.ToString());
}


#### 5.10 静态成员


使用类名调用 `static` 成员:`ClassName.StaticMember`。  
 这种做法通过明确静态访问使代码更易于阅读。 请勿使用派生类的名称来限定基类中定义的静态成员。


编译该代码时,代码可读性具有误导性,如果向派生类添加具有相同名称的静态成员,代码可能会被破坏。


#### 5.11 OOP面向对象规约


1.避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可


2.不能使用过时的类或方法(`[Obsolate]标识`)  
 说明:C#中对于标记过时的方法,有可能会在新版本的`.Net Framework`中剔除,因此不建议继续使用此类或方法。


3.Object 的`Equals`方法容易抛空引用异常,应使用常量或确定有值得对象来调用Equals。



	//反例
	"XiaoY".Equals(gameObject.tag);
	//正例
	gameObject.tag.Equals("XiaoY");

4.`构造方法`中禁止加入业务逻辑,如有初始化逻辑等,请放在Init() 方法中。


5.当一个类有多个构造方法,或多个同名方法,这些方法应该按照顺序放置在一起,便于阅读。


6.类内方法定义顺序依次是:常量、字段、属性、方法,按照public -> protected -> private 排序。


7.类成员与方法访问控制从严


* 如果不允许外部直接通过new来创建对象,那么构造方法必须是private。
* 工具类不允许有public或default构造方法。
* 类非static成员变量并且与子类共享,必须是protected。
* 类非static成员变量并且仅在本类使用,必须是private。
* 类static成员变量如果仅在本类使用,必须是private。
* 类成员方法只供内部调用,必须是private。
* 类成员方法只对继承类公开,那么限制为protected


说明:任何类、方法、参数、变量,严控访问范围,过宽泛的访问范围,不利于模块解耦。如果一个private的方法,想删除就删除,可是一个public的Service方法,或者一个public的成员变量,删除一下,造成的损失可能没办法完全掌控。所以在一开始创建该类时就应该将访问明码标价,防止后期出现其他问题。



**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)**
![img](https://img-blog.csdnimg.cn/img_convert/f097ac004de69903c363dfa67310b364.png)

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

。


7.类成员与方法访问控制从严


* 如果不允许外部直接通过new来创建对象,那么构造方法必须是private。
* 工具类不允许有public或default构造方法。
* 类非static成员变量并且与子类共享,必须是protected。
* 类非static成员变量并且仅在本类使用,必须是private。
* 类static成员变量如果仅在本类使用,必须是private。
* 类成员方法只供内部调用,必须是private。
* 类成员方法只对继承类公开,那么限制为protected


说明:任何类、方法、参数、变量,严控访问范围,过宽泛的访问范围,不利于模块解耦。如果一个private的方法,想删除就删除,可是一个public的Service方法,或者一个public的成员变量,删除一下,造成的损失可能没办法完全掌控。所以在一开始创建该类时就应该将访问明码标价,防止后期出现其他问题。



**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)**
[外链图片转存中...(img-9bLvWZ7E-1713362755341)]

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值