C#编程深入研究变量,类型和方法(一)

简介: C#编程深入研究变量,类型和方法

本文主要来自<>哈里森.费隆 著,仅用为做笔记。

编写正确的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 按钮,那么脚本仍将像以前那样正常工作。

image.png

使用类型


为变量分配特定类型是一项重要决定,这会深入影响恋最涉及的每个交互。C#是种强类型或类型安全的语言,这意味着每个变量都有数据类型,同时还意味着当执行运算或者将给定的变量转换为另一种类型时,在在特定的规则必须遵循。

通用内置类型


C#中的所有数据类型都派生自同一个祖先 System.Obiect。这种称为通用类型系统(Common Type System,CTS)的层次结构意味着不同类型有很多功能能够共享。图列出了一些最常见的数据类型以及它们所能够存储的值。

数据类型 变量内容
int 整数,比如数字3
float 浮点数,比如3.14
string 字符串,比如"watch me go now"
bool 布尔值

除了指定变量可以存储的值的类型之外,还可以指定有关变量自身的附加信息,比如:

  • 所需的存储空间
  • 最小值和最大值
  • 允许执行的运算
  • 在内存中的位置
  • 访问方法
  • 基本(派生)类型。

使用 C#提供的所有类型是使用文档而非依靠记忆的完美示例。很快,即使使用最复杂的自定义类型,你也会感觉像是第二天性。

1.实践---处理不同的类型

下面继续,打开LeamingCurve 脚本,在下图 所示的通用内置类型部分为上图中的每一种类型添加一个新的变量。选择名称和值,确保它们被标记为 public,这样才可以在Inspector面板中看到它们。

image.png

刚刚发生了什么

在lspector 面板中,不同的变量类现在是可见的,留意显示为复选框的布量(true 表示选中,false 表示未选中),

image.png

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月示。也可以使用+运算符创建内插字符串,我们会在后面进行介绍。

image.png

类型转换


我们已经看到,变量只能保存它们声明的那种类型的值。但某些情况下,我们需要组合或分配不同的变量类型。在编程术语中,这叫作转换,转换主要有两种形式:隐式转换和显式转换。

  • 隐式转换会自动发生,通常发生在较小的值适合另一种变量类型且无须四舍五入的情况下。例如,任何整数都可以隐式转换为 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;

注意:请记住,使用驼峰式命名风格的变量名以小写字母开头,然后每个单词的首宇母大写。驼峰式命名还明确区分了变量名和类名,后者以大写字母开头.


这样就好多了。稍加思考之后,我们更新了变量名的含义和上下文。由于对变量名的长度没有技术上的限制,你可能发现自己有些过头,写出了可笑的描述性名称,这肯定会给自己带来问题,就像短的非描述性名称一样。


作为一般规则,变量名应具有一定的描述作用---不要太长,也不要太短。找到自己的风格并坚持下去即可。

相关文章
|
15天前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
29 3
|
7天前
|
JSON 程序员 C#
使用 C# 比较两个对象是否相等的7个方法总结
比较对象是编程中的一项基本技能,在实际业务中经常碰到,比如在ERP系统中,企业的信息非常重要,每一次更新,都需要比较记录更新前后企业的信息,直接比较通常只能告诉我们它们是否指向同一个内存地址,那我们应该怎么办呢?分享 7 个方法给你!
|
10天前
|
C# UED SEO
C# 异步方法async / await任务超时处理
通过使用 `Task.WhenAny`和 `Task.Delay`方法,您可以在C#中有效地实现异步任务的超时处理机制。这种方法允许您在指定时间内等待任务完成,并在任务超时时采取适当的措施,如抛出异常或执行备用操作。希望本文提供的详细解释和代码示例能帮助您在实际项目中更好地处理异步任务超时问题,提升应用程序的可靠性和用户体验。
32 3
|
20天前
|
编译器 C#
c# - 运算符<<不能应用于long和long类型的操作数
在C#中,左移运算符的第二个操作数必须是 `int`类型,因此需要将 `long`类型的位移计数显式转换为 `int`类型。这种转换需要注意数据丢失和负值处理的问题。通过本文的详细说明和示例代码,相信可以帮助你在实际开发中正确使用左移运算符。
27 3
|
19天前
|
编译器 C#
c# - 运算符<<不能应用于long和long类型的操作数
在C#中,左移运算符的第二个操作数必须是 `int`类型,因此需要将 `long`类型的位移计数显式转换为 `int`类型。这种转换需要注意数据丢失和负值处理的问题。通过本文的详细说明和示例代码,相信可以帮助你在实际开发中正确使用左移运算符。
34 1
|
17天前
|
编译器 C#
c# - 运算符<<不能应用于long和long类型的操作数
在C#中,左移运算符的第二个操作数必须是 `int`类型,因此需要将 `long`类型的位移计数显式转换为 `int`类型。这种转换需要注意数据丢失和负值处理的问题。通过本文的详细说明和示例代码,相信可以帮助你在实际开发中正确使用左移运算符。
10 0
|
1月前
|
存储 C#
【C#】大批量判断文件是否存在的两种方法效率对比
【C#】大批量判断文件是否存在的两种方法效率对比
40 1
|
1月前
|
安全 C# 数据安全/隐私保护
实现C#编程文件夹加锁保护
【10月更文挑战第16天】本文介绍了两种用 C# 实现文件夹保护的方法:一是通过设置文件系统权限,阻止普通用户访问;二是使用加密技术,对文件夹中的文件进行加密,防止未授权访问。提供了示例代码和使用方法,适用于不同安全需求的场景。
102 0
|
6月前
|
开发框架 前端开发 .NET
C#编程与Web开发
【4月更文挑战第21天】本文探讨了C#在Web开发中的应用,包括使用ASP.NET框架、MVC模式、Web API和Entity Framework。C#作为.NET框架的主要语言,结合这些工具,能创建动态、高效的Web应用。实际案例涉及企业级应用、电子商务和社交媒体平台。尽管面临竞争和挑战,但C#在Web开发领域的前景将持续拓展。
192 3
|
6月前
|
SQL 开发框架 安全
C#编程与多线程处理
【4月更文挑战第21天】探索C#多线程处理,提升程序性能与响应性。了解C#中的Thread、Task类及Async/Await关键字,掌握线程同步与安全,实践并发计算、网络服务及UI优化。跟随未来发展趋势,利用C#打造高效应用。
199 3