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

article/2025/10/14 18:27:16

请添加图片描述

  • 🎬 博客主页:https://xiaoy.blog.csdn.net

  • 🎥 本文由 呆呆敲代码的小Y 原创,首发于 CSDN🙉

  • 🎄 学习专栏推荐:Unity精品学习专栏

  • 🌲 游戏制作专栏推荐:游戏制作分享

  • 🌲Unity实战100例专栏推荐:Unity 实战100例 教程

  • 🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!

  • 📆 未来很长,值得我们全力奔赴更美好的生活✨

  • ------------------❤️分割线❤️-----------------------


      • 前言
  • 【编码规范篇】| C# 代码规范总结,包括命名规范,代码规范 注释规范等
    • 一、编码规范
      • 1.1 什么是编码规范 / Coding standards ?
      • 1.2 编码规范必要性
      • 1.3 编码规范优点
    • 二、命名规范
      • 2.1 帕斯卡拼写法(Pascal)
      • 2.2 驼峰命名法(camelCasing)
      • 2.3 其他命名约定
    • 三、布局规范
    • 四、注释规范
    • 五、代码规范/语言准则
      • 5.1 字符串数据类型
      • 5.2 隐式类型本地变量
      • 5.3 无符号数据类型
      • 5.4 数组
      • 5.5 委托
      • 5.6 异常处理
      • 5.7 && 和 || 运算符
      • 5.8 new 运算符 使用对象初始化值设定简化对象创建
      • 5.9 事件处理
      • 5.10 静态成员
      • 5.11 OOP面向对象规约
      • 5.12 控制语句
    • 总结
    • 👑 评论区抽奖送书

请添加图片描述


前言

  • 在我们程序员日常开发的过程中,会编写代码是一个最基本且常规的操作。

  • 而作为一名合格的软件工程师,出产物就应该具备工程的健壮性美观性,因此编码规范是作为软件工程师的职业素养。

  • 但是就 编码规范 而言,可能大多数程序员都是按照自己的长久习惯进行代码编写,并没有遵循一个约定好的编码规范。

  • 所以本篇就来对C#中的编码规范做一个详细的总结整理,并对一些超级常用的做一个重点解析!

  • 对于编程而言,大多数语言的编码规范基本上是遵循一些相同的规范标准的,除去少些个语言有一些特殊用法之外。

  • 所以本篇文章不止对使用C#工程师们有帮助哦,不使用C#的小伙伴也可以看看跟自己平时用的语言有什么编码差异吧!


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

请添加图片描述


一、编码规范

1.1 什么是编码规范 / Coding standards ?

  • Coding standards are collections of rules and guidelines that determine the programming style, procedures, and methods for a programming language.
  • Think of coding standards as a set of rules, techniques, and best practices to create cleaner, more readable, more efficient code with minimal errors. They offer a uniform format by which software engineers can use to build sophisticated and highly functional code.
  • 编码规范是针对某种编程语言的,决定编程风格、过程和方法的一系列规则和指导方针的集合。
  • 把编码规范看作是一套规则、技术和最佳实践,以创建更清爽、更可读、更有效的代码,并将错误降到最低。它们提供了一个统一的格式,软件工程师可以用它来构建复杂和功能强大的代码。

1.2 编码规范必要性

  • 作为一名合格的软件工程师,出产物就应该具备工程的健壮性和美观性,因此编码规范是作为软件工程师的职业素养。
  • 如果在学习编程的初期,已经认真学习过编码规范的话,那自然是没有什么任何问题的。
  • 但是对于很多初学者来说,可能对这方面并没有重视起来,还是依据自己的想法对变量方法等等随意命名。
  • 代码不规范对于实现项目中的功能来说并没有什么太大的问题,这就好比一个人懂不懂礼貌一样,一样可以活的随心所欲。
  • 而对我们亲手编写的代码有一个规范化的管理则是我们对编程的一个最基本的尊重。
  • 所以非常建议初学者们一定要对编码规范多用点心,只要初期对这方面有一个基本的认知就可以养成一个好习惯,摆脱杂乱无章的代码啦!
  • 如果没有预先规定所有团队成员应该遵守的规范,会导致降低工程师的积极性、增加开发时间、产生复杂的代码结构等等情况。

  如果没有编码规范,团队中的每个人都按自己的编码风格来。在不久的将来,维护和调试代码将变得不容易。

  有一套编码标准在手,更容易保持代码的清晰和易于协作。当然,标准因应用、性质、行业、项目、开发人员技能和多种因素而不同。
对于一个开发团队来说,在开发过程中拥有适当的编码规范和标准是至关重要的,这将有助于团队保持代码质量,并减少新的开发人员试图理解复杂的代码库所花费的时间。

1.3 编码规范优点

  • 可有效的提高代码质量,并易于维护
  • 减少代码的复杂性
  • 易于团队合作,降低开发成本
  • 为不同工程师创建的代码提供统一规范
  • 创建出可复用的代码
  • 使得检测错误更加容易
  • 使代码更简单,更可读,更容易维护
  • 促进更合理的编程实践,提升程序员的效率,更快完成目标
  • 编码指南有助于在早期阶段发现错误,所以它有助于减少软件项目的额外成本。
  • 减少了开发软件的隐藏成本。

二、命名规范

C# 的命名有两种约定:帕斯卡拼写法(Pascal)驼峰命名法(camelCasing)

  • 帕斯卡拼写法(Pascal): 成员名的每个单词的首位字母大写,如:Student,StudentName,StudentParentName。
  • 驼峰命名法(camelCasing):成员名除了第一个单词外其余首字母都大写,Student,studentName,studentParentName.

2.1 帕斯卡拼写法(Pascal)

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 SysuserControllerpublic class OrderFactorypublic 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");elseConsole.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的成员变量,删除一下,造成的损失可能没办法完全掌控。所以在一开始创建该类时就应该将访问明码标价,防止后期出现其他问题。

5.12 控制语句

1.在一个switch块内,每个case要么通过break/return等来终止,要么注释说明程序将继续执行到哪一个case为止:在一个switch块内,都必须包含一个default语句,并且放在最后,即使它什么代码都没有。

2.在 if / else / for / while / do 语句中都必须使用大括号,即使只有一行代码,避免使用下面的形式: if (condition) do something…

3.循环体内的语句要考虑性能,以下操作尽量移至循环体外处理,如定义对象、变量、获取数据库连接


总结

  • 本文整理了一些C#中较为常用的一些编码规范,目的是能够让我们编写出更优美简洁的代码。
  • 多数的规范并没有强制性,只是作为一个样例模板以供参考学习使用。
  • 尤其是对于新手来说,在前期编写代码的过程中养成一个好的习惯,后面就可以完全放飞自我啦。
  • 如果文中哪里有错误或者有更好的解决方案,也希望可以指出共同进步~
  • 部分内容参考链接 C# 7 草稿规范。

👑 评论区抽奖送书

最后在评论区进行抽取三名 送出优质评论的幸运小伙伴 送下面这本书籍

  • 博主这有一些Unity相关的书籍,是由 清华大学出版社 赞助的,在此感谢~大家喜欢的也可以去官方购买!

  • 在这里搞个小活动抽奖送给大家,对看书感兴趣的小伙伴可以参加一波呀,刚开始可能参与的不多,抽中概率很大哦!

  • 《Unity游戏优化(第三版)》

  • 一本非常经典的Unity编程宝典,可以迅速提高编程水平!

  • 尤其是想从事Unity开发的小伙伴,这本书就可以让你了解相关知识,对症下药可以极大地提高学习效率!
    在这里插入图片描述

🎁抽奖规则

规则如下:

🚀 规则如下🚀
  • 给本篇博客文章 点赞 收藏 评论 三连,然后在评论区评论里 送一本书籍,总共抽三本!
  • 为优质评论抽中的概率更大哦,其中评论点赞数排名第一的小伙伴必中一本,快去喊你的小伙伴给你点赞吧!
  • 总共抽三本,中的几率还是很大的哦~ 想看书的小伙伴参与起来!
  • 中奖信息本周日下午本篇文章评论区公布!记得留意呀!
  • 没抽到的,但是喜欢这本书的小伙伴也可以在网上自行购买哈,官方正品商店购买即可!
🚀 规则如上🚀

🎄《《Unity游戏优化(第三版)》推荐理由(⭐⭐⭐⭐⭐)

图书简介

  • 使用Unity Profiler发现程序中的瓶颈并找到解决方法
  • 发现VR项目中关键的性能问题,并学习如何处理它们
  • 以易用的方式增强着色器,通过细微而有效的性能调整优化它们
  • 使用物理引擎使场景尽可能动态化
  • 组织、过滤和压缩艺术资源,在保持高品质的同时实现性能化
  • 使用Mono框架和C#实现内存利用大化,以及优化GC

书本图片如下,喜欢的小伙伴参与起来!也可以京东链接自行购买哦~

喜欢的小伙伴可以尝试抽奖一下呀!

抽不到的小伙伴喜欢的也可以自行购买哦,这本书还是很不错的!


在这里插入图片描述


http://chatgpt.dhexx.cn/article/h6S7CDF3.shtml

相关文章

编码的一些基本规范

1. 数据库表设计 Rule 1. 【强制】表名小写&#xff0c;多个word之间用英文下横线_分隔Rule 2. 【强制】表名普通表前缀t_;临时表tmp_;备份表bak_;视图v_;主键pk_;外键fk_;唯一索引uix_;普通索引idx_Rule 3. 【强制】关系表统一用relation结尾Rule 4. 【强制】表名和业务字段必…

编码规范汇总【持续更新】

目录 前言规范标准C规范C#规范 规范记录命名硬编码单例类【线程安全】Qt定义类【隐式内存共享】 前言 作为软件工程师&#xff0c;出产物就应该具备工程的健壮性和美观性。因此代码规范是作为软件工程师的职业素养。但总所周知&#xff0c;程序员的工作基本就是在维护一座屎山…

51单片机串口波特率

SCON SCON 0X50工作方式1 波特率需要使用定时器1 波特率 ((2^SMOD)/32) * (定时器溢出率) 定时器溢出率 系统时钟/指令周期/装载数 SMOD 1 &#xff0c;波特率加倍 TH1 TL1 -(FOSC / INSTRU_CYCLE / 32 / BAUD); //Set auto-reload vaule TR1 1;

关于51单片机串口1发送完整的数据包

关于51单片机串口1发送完整的数据包 在参考这样的协议的条件下我们想发送一套完整的数据包该如何发送呢&#xff1f;可以设计这样的程序。 1. 串行口1接收特定包头数据包函数。 参数: Uart_Rec_Data&#xff1a;串口接收到的数据 &#xff1b; USER_Get_DataPacket: 数据存储目…

51单片机串口收发

#include<reg52.h>#define uint unsigned int #define uchar unsigned char/*本代码实现串口的收发功能&#xff0c;PC发送什么单片机就接收什么&#xff0c; 然后单片机又把接收的发出去&#xff0c;本次编写了在发送单个字符串 函数上添加了字符串函数&#xff0c;方便…

学习51单片机串口工作方式及应用

1.串口控制寄存器SCON SM2:多机通信控制位 REN:允许接收控制位 TB8:发送第九位数据 RB8:接收第九位数据 TI:发送中断标志位 RI:接收中断标志位 2.电源控制寄存器PCON 当SMOD位为1&#xff0c;则串行口方式1、方式2、方式3的波特率加倍。 3.串口的工作方式 &#xff08;1…

关于51单片机串口通信的相关知识(寄存器)

一、51单片机串口概念 1、51单片机的串行口 51单片机的串行口是一个可编程全双工的通信接口&#xff0c;具有UART&#xff08;通用异步收发器&#xff09;的全部功能。 2、51单片机的硬件连接 简单双向串口通信有两根数据通信线&#xff1a; 发送端TXD&#xff08;Transmit Da…

C51单片机串口点亮一个led

C51单片机串口点亮一个led 因为最近要用到51的串口做一些通信&#xff0c;这里写一个点led的程序记录一下。 说是一个led&#xff0c;其实可以随意多个。 主要使用到的东西&#xff1a; STC89C52芯片&#xff0c;USB转TTL下载器&#xff0c;led灯若干&#xff0c;面包板&am…

51单片机 串口

串口说白了&#xff0c;就是初始化后&#xff0c;用中断接收发送字符而已。 TXD 是 80C51 单片机的P3.1口&#xff0c;RXD 是80C51 单片机的 P3.0口 T1 溢出率 是定时器1的溢出率 &#xff0c;SMOD是发送速率倍频的16分频&#xff0c;T1每溢出一次发送一位&#xff0c;每次发送…

【记录】一次51单片机串口乱码问题排查

【记录】一次51单片机串口乱码问题排查 项目场景问题描述原因分析解决方案结语 项目场景 在51串口收发仿真实验中使用两个单片机互相通信&#xff0c;程序设定A上电1s后通过串口以16进制给B发送AA,直到B收到AA后回复BB&#xff0c;当A机确认收到AA后开始发送数据&#xff0c;若…

## 51单片机串口通讯

1&#xff0c;接线方式&#xff1a; RXD: 数据输入引脚&#xff1b;对应stc89的P3.0口&#xff1b; TXD&#xff1a;数据的发送端口;对应P3.1口&#xff1b; 注意&#xff1a;单片机的的串口TX&#xff0c;RX与外设交叉接线&#xff1b; 2串口编程要素 输出/输入数据缓冲器S…

51单片机串口通信详解

文章目录 前言一、计算机通信简介二、串口通信简介1、简介2、同步通信和异步通信2.1 同步通信2.2 异步通信 3、串行通信的传输方式4、串口通信硬件电路5、常见接口介绍 三、串口相关寄存器详解1、特殊功能寄存器SCON2、PCON寄存器3、TMOD寄存器&#xff08;定时器工作方式寄存器…

51单片机串口接收处理

目的: 通过51单片机串口外设功能&#xff0c;来对一组数据进行处理&#xff0c;新手刚刚入门可能会将串口接收到的一个数据直接赋值给一个变量&#xff0c;然后用这个变量做相应功能&#xff0c;可是这样写的不稳定性太高了&#xff0c;有可能会接收不到你要的那个数据&#…

51单片机串口通信原理

计算机串行通信基础 通信有串行通信和并行通信两种方式 串行通信&#xff1a; 将数据字节分为一位一位的形式在一条数据线上逐个传送。如下图所示 串行通信特点&#xff1a;传输线少&#xff0c;长距离传送时成本低&#xff0c;且可以利用电话网等现成设备&#xff0c;但数据的…

51单片机串口点灯

#include "reg52.h" #include "intrins.h" sfr AUXR 0x8e; sbit D5 P3^7; //定义led 接在P3.7void UartInit(void) //9600bps11.0592MHz {SCON 0x50; //配置串口工作方式1&#xff0c;RE使能接收数据 0101 0000PCON 0x00; TMOD &0x0F;TMOD |0x2…

51单片机串口使用

文章目录 前言一、串口概念二、中断中的RI、TI和SUBF1.RI2.TI3.SUBF 三、串口波特率的计算四、代码的编写总结 前言 今天将为大家讲解51单片机的串口原理及代码编写。 一、串口概念 51单片机串口是一种通信接口&#xff0c;它可以将51单片机与外部设备连接起来&#xff0c;实…

51单片机串口通信

串口通信 1、通信的基本概念2、 51单片机串口介绍2.1、串口通信简介2.2、串口内部结构2.3、串口通信寄存器SCONPCON 2.4、串口工作方式 3、串口使用方法3.1、硬件3.2、通信协议RS2323.3、串口初始化 4、硬件设计5、 软件设计6、拓展 串口的通信&#xff0c;一般是检测通信模块是…

UART串口通信

什么是串行通信? 将数据字节分成一位一位的形式在一条传输线上逐位地发送。 优点:成本低,控制复杂。 什么是异步通信? 异步通信是指通信的发送与接收设备使用各自的时钟控制数据的发送和接收过程。为使双方的收发协调,要求发送和接收设备的时钟尽可能一致。 异步通信的两…

MCU-51:单片机串口详解

目录 一、计算机通信简介二、串口通信简介2.1 同步通信2.2 异步通信 三、串行通信的传输方式四、串口通信硬件电路五、常见接口介绍六、串口相关寄存器详解6.1 特殊功能寄存器SCON6.2 PCON寄存器6.3 TMOD寄存器 七、代码演示-单片机和电脑通信7.1 串口向电脑发送数据7.2 电脑通…

51单片机学习入门(三):串口

1.串口是什么&#xff1f; 串口是一种应用十分广泛的通讯接口&#xff0c;串口成本低、容易使用、通信线路简单&#xff0c;可实现两个设备的互相通信。单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信。 51单片机内部自带UART&#xff08;…