本文主要来自<>哈里森.费隆 著,仅用为做笔记。
编写正确的C#代码
代码行的功能类似于句子,这意味着它们需要具有某种分隔或结束字符。在C#中,所有被称为语句的代码行都以分号结尾,分号用于将语句分开,以便代码编辑器进行处理。
与通常情况下的书面文字不同,C#语句从技术上讲不必位于一行。代码编辑器怒感空格和换行符。例如,一个简单的变最可以有不同的写法。可以按如下方式进行编写:
public int firstName "Bilbo";
也可以这样编写:
1. public 2. int 3. firstName 4. = 5. "Bilbo";
以上两种写法 Visual Studio 都可以接受,但是强烈建议不要使用第二种写法,因为这会使代码极难阅读。
方法或类后面的花括号的标准格式是在新的一行包含每条语句,如下所示:
public void MethodName () { }
但在创建新脚本或者在线访问 Unity 文档时,你会看到第一个花括号与声明位于同一行:
1. public void MethodName() { 2. 3. }
虽然这并不是什么让人抓狂的事情,但尽早理解这些细微差别是很重要的。
简单的调试技术
在处理实际问题时,我们需要一种方式来把信息和反馈打印到控制台。为此,人们引入了调试的概念,C#和 Unity 提供了简化调试过程的辅助方法。每当需要调试或打印一些信息时,请使用以下方法:
- 对于简单的文本或单个变量,请使用 Debug.Log0方法。文本必须在括号内,
- 并且变量可以直接使用而无须添加字符:
1. Debug.Log("Text goes here."); 2. Debug.Log(yourVariable);
- 对于更复杂的调试,可以使用 Debug.LogFormat0方法。通过使用一对用花括号标识的占位符,可以在打印文本中放置变量。每组花括号都包含一个从 0开始的索引,对应于一个顺序变量。
在下面的示例中,q0占位符被替换为变量 variable1 的值,1占位符被替换为变量 variable2 的值,以此类推:
Debug.LogFormat("Text goes here, add (0) and (1) as variableplaceholders",variablel,variable2);
变量的语法
我们已经看到变量是如何创建的,并且涉足变量提供的一些高级功能,但我们仍然缺少使这一切成为可能的语法。变量不仅仅出现在 C#脚本的顶部,它们还必须根据特定的规则和要求进行声明。变量需要满足以下基本要求:
- 需要指定变量存储的数据类型。
- 变量必须具有唯一的名称。
- 为变量指定的值必须匹配指定的类型。
- 变量的声明必须以分号结尾。
以下语法能够满足上述基本要求:
dataType uniqueName = value;
以上方式简单、整洁、有效。但如果变量只有这一种创建方式,那么从长远看,这不利于 C#语言的发展。复杂的应用程序和游戏都有不同的用例和场景,所有这些都需要使用独特的C#语法。
声明类型和值
创建变量的最常见场景就是拥有所有可用数据时。例如,如果我们知道玩家的年龄,存储起来就很简单,如下所示:
int currentAge =32:
以上语句能够满足变量的所有基本要求:
- 指定了数据类型 imt。
- 使用了唯一的名称currentAge
- 32是整数,与指定的数据类型匹配
- 语句以分号结尾。
仅声明类型
考虑另一种场景:知道变量存储的数据类型和名称,但不知道值。值将在其他地方计算和分配,但仍然需要在脚本的顶部声明变量。
对于这种情况,可以仅声明类型,如下所示:
int currentAge;
以上语句只定义了类型int 和唯一的名称 currentAge,但由于能够满足变量的所有基本要求,因此仍然有效。如果没有赋值,那么默认会根据变量的类型来赋值。在这种情况下,curentAge 默认为0以匹配 int 类型。当实际值可用时,就可以在单独的语句中轻松进行设置:
currentAge =32;
访问修饰符
既然基本语法不再是个谜,现在让我们深入了解变量语句的细节。由于我们习惯从左向右阅读代码,因此从一个我们还没有讨论过的主题开始对变量进行深入研究是有意义的:访问修饰符。
快速回顾一下我们在 LearmingCurve 脚本中使用的变量,你会发现语句的前面都有额外的关键字public。public 就是变量的访问修饰符。可以将其视为安全设置,用于确定哪些对象可以访问变量的信息。
注意:任何未标记为public 的变量都不会显示在 Unity 的Inspector 面板中.
如果加上访问修饰符,那么更新后的语法如下所示:
accessModifier dataType uniqueName = value;
尽管使用访问修饰符对于声明变量来说不是必要的,但对于新手来说,这是个好习惯。
选择安全级别
C#有四个访问修饰符,但是作为初学者,最常用的是如下两个。
- public:对任何脚本开放,不受限制。
- private:变量仅在创建它们的类(称为所属类)中可用。没有使用访问修饰符声
明的任何变量默认都是私有的。
另外两个访问修饰符如下。
- protected:变量在所属类或派生类中可以访问
- internal:仅在当前程序集中可用。
每个访问修饰符都有特定的用例,但是在继续学习之前,我们不用担心 protected和internal。
实践一一使变量私有
就像现实生活中的信息一样,有些数据需要进行保护或与特定的人共享。工个量如果不需要在 lmsprctor 面板中进行据需激进脚本进行访同,那么最好使用private访问修饰符进行声明。
下面执行以下步骤,更新 LearningCurve 脚本:
(1)把 rsNumber 前面的访间修饰符从 public 改为 private, 然后保存文件
(2)返回 Unity,选择 Main Camer,看看 Leaming Curve 部分有什么变化
刚刚发生了什么
firstNumber 现在由于是私有的,因此在 Inspector 面板中不可见,并且只能在Leaming Curve 中进行访问,如图 3-1 所示。如果单击 Play 按钮,那么脚本仍将像以前那样正常工作。
使用类型
为变量分配特定类型是一项重要决定,这会深入影响恋最涉及的每个交互。C#是种强类型或类型安全的语言,这意味着每个变量都有数据类型,同时还意味着当执行运算或者将给定的变量转换为另一种类型时,在在特定的规则必须遵循。
通用内置类型
C#中的所有数据类型都派生自同一个祖先 System.Obiect。这种称为通用类型系统(Common Type System,CTS)的层次结构意味着不同类型有很多功能能够共享。图列出了一些最常见的数据类型以及它们所能够存储的值。
数据类型 | 变量内容 |
int | 整数,比如数字3 |
float | 浮点数,比如3.14 |
string | 字符串,比如"watch me go now" |
bool | 布尔值 |
除了指定变量可以存储的值的类型之外,还可以指定有关变量自身的附加信息,比如:
- 所需的存储空间
- 最小值和最大值
- 允许执行的运算
- 在内存中的位置
- 访问方法
- 基本(派生)类型。
使用 C#提供的所有类型是使用文档而非依靠记忆的完美示例。很快,即使使用最复杂的自定义类型,你也会感觉像是第二天性。
1.实践---处理不同的类型
下面继续,打开LeamingCurve 脚本,在下图 所示的通用内置类型部分为上图中的每一种类型添加一个新的变量。选择名称和值,确保它们被标记为 public,这样才可以在Inspector面板中看到它们。
刚刚发生了什么
在lspector 面板中,不同的变量类现在是可见的,留意显示为复选框的布量(true 表示选中,false 表示未选中),
2.实践---创建内插字符串
数值类型的行为与数学中的一样,但字符串是另一回事。我们通常以S字符开头把变量和字面值直接插入文本,这称为学符串插值(tring intepolatio)。插入的值将被添加到花括号中,就像使用 LogFommat 方法一样。下面让我们在 LeamingCurve 脚本中创建一个简单的内插字符串,看看效果。
// Use this for initialization void Start() { Debug.Log($"A string can have variables Like {firstName} inserted directly!"); }
刚刚发生了什么
由于有了花括号,firstName 变量的值得以在内插字符串中打印出来,如图36月示。也可以使用+运算符创建内插字符串,我们会在后面进行介绍。
类型转换
我们已经看到,变量只能保存它们声明的那种类型的值。但某些情况下,我们需要组合或分配不同的变量类型。在编程术语中,这叫作转换,转换主要有两种形式:隐式转换和显式转换。
- 隐式转换会自动发生,通常发生在较小的值适合另一种变量类型且无须四舍五入的情况下。例如,任何整数都可以隐式转换为 double或float 类型,而不需要编写额外的代码.
float implicitConversion = 3;
当转换过程中存在丢失变量信息的风险时,需要进行显式转换。例如,如果想把 double 类型的值转换为整数,就必须在想要转换的值之前添加目标类型到圆括号中以显式地进行类型转换。这相当于告诉编译器,我们知道数据(或精度)可能会丢失。在如下显式转换中,3.14 被四舍五入为 3,失去了小数部分。
int explicitConversion = (int)3.14;
推断式声明
到目前为止,我们已经学习了类型的交互、操作和转换规则,但是如何处理需要存储未知类型的变量的情况呢?这听起来可能有些让人抓狂,但是想想数据下载场景我们知道信息会进入游戏,但不知道它们会以什么形式出现。
幸运的是,C#能够从赋值推断出变量的类型。var 关键字使程序知晓 currentAge变量的类型由值32决定:
var currentAge = 32;
自定义类型
当我们讨论数据类型时,很重要的一点就是:要尽早了解数字和单词(又称为字值)并不是变量可以存储的唯一值。例如,类、结构和枚举都可存储为变量,我们将第5章介绍这些主题,更详细的内容将在第 10章介绍。
类型综述
类型很复杂,熟悉它们的唯一方法就是使用它们。然而,以下一些重要的原则要记住:
- 所有变量都需要具有指定的类型(无论是显式的还是推断式的)。
- 变量只能保存指定类型的值(比如,不能将字符串赋值给 int变量)。
- 每种类型都有一组能用和不能用的运算符(不能用另一个值去减布尔值)。
- 如果一个变量需要用其他类型的变量进行赋值或组合使用的话,那么需要对它们进行转换(隐式转换或显式转换)。
- C#编译器可以使用 var 关键字从变量的值推断出变量的类型,但仅应在变量的类型未知时使用。
命名变量
我们已经学习了访问修饰符和类型,对变量进行命名似乎是事后才想到的事,这并不是草率的选择。清晰且一致的命名约定不仅能使代码更具可读性,而且能确团队中的其他开发人员无须询问就能理解代码编写者的意图。
最佳实践
命名变量的第一条则就是变量名要有意义,其次是要使用驼峰式命名风格。在戏中,如果声明如下变量来存储玩家的健康状况:
public int health = 100;
你的脑海中应该会出现一连串的问题。谁的健康状况?存储的是最大值还是最值?当值发生更改时,其他代码会受到什么影响?这些问题都可以通过使用一个有意)的变量名来轻松地回答。
使用如下方式命名变量可能更合适一些:
public int maxCharacterHealth = 100;
注意:请记住,使用驼峰式命名风格的变量名以小写字母开头,然后每个单词的首宇母大写。驼峰式命名还明确区分了变量名和类名,后者以大写字母开头.
这样就好多了。稍加思考之后,我们更新了变量名的含义和上下文。由于对变量名的长度没有技术上的限制,你可能发现自己有些过头,写出了可笑的描述性名称,这肯定会给自己带来问题,就像短的非描述性名称一样。
作为一般规则,变量名应具有一定的描述作用---不要太长,也不要太短。找到自己的风格并坚持下去即可。