AI 摘要

C#入门教程全面总结基础语法与核心知识,涵盖变量类型、常量、转义字符、类型转换、异常捕获、运算符及循环逻辑。

一、变量

在入门要求下,C#【1】 中的变量类型可大致分为 整数、小数、字符类、布尔类型四大类。

1.变量类型

1.整数类型

整数类型变量又可分为有符号整数、无符号整数两类,以下是详细区分

类型位数取值范围
sbyte8位-128 ~ 127
byte8位0 ~ 255
short16位-32,768 ~ 32,767
ushort16位0 ~ 65,535
int32位约 -21亿 ~ 21亿
uint32位0 ~ 约42亿
long64位很大的正负整数
ulong64位很大的非负整数

对于取值范围可以从数字位数的角度理解,比如int【2】类型,总共有32位,最左边第一位数字代表符号位(1为负、0为正),剩下31位可用于表示数字,因此其数字范围是正负231-1。

例如:

byte age = 18;
int population = 1_400_000_000;
long distance = 9_000_000_000L;
uint count = 100U;

在实际游戏开发中,通常先使用int;数字超过int范围后再使用long【3】类型。

2.小数类型

小数类型可分为二进制浮点数和高精度十进制数字

类型位数有效精度适合场景
float32位约6~9位数字图形、游戏等
double64位约15~17位数字普通小数计算,默认选择
decimal128位约28~29位数字金额、财务等高精度计算
float height = 1.75F;       // 必须加 F
double pi = 3.1415926535;   // 小数字面量默认是 double
decimal price = 99.99M;     // 必须加 M

floatdouble 可能产生小数误差:

double result = 0.1 + 0.2;  // 可能不是精确的 0.3

涉及金钱时通常使用 decimal

3.字符类型

char 表示一个 UTF-16【4】 编码单元,使用单引号:

char grade = 'A';
char chinese = '中';
char newLine = '\n';

注意:部分 emoji 需要两个 char 才能表示,因此 char 不一定等同于用户看到的一个完整字符。

string 表示零个或多个字符组成的文本,使用双引号:

string name = "张三";
string message = "Hello, C#!";
string empty = "";

stringchar 的区别:

char letter = 'A';       // 单引号,一个字符
string word = "Apple";   // 双引号,一串字符

4. 布尔类型

布尔类型只有 truefalse 两个值:

bool isStudent = true;
bool isFinished = false;

其主要作用是用于条件判断

2.变量的本质

1.定义与特征

变量就是:一个有名称、有类型、能够保存数据的位置。一个变量通常具有:

  1. 类型:可以保存什么数据。
  2. 名称:如何访问这个变量。
  3. :当前保存的数据。
  4. 作用域:可以在哪些位置使用。
if (true)
{
    int score = 100;
    Console.WriteLine(score); // 可以使用
}

// Console.WriteLine(score);  // 错误,超出作用域

2.值类型与引用类型

变量除了通过数据类型分类外,还可以通过值类型【5】引用类型【6】

整数、小数、布尔和字符通常属于值类型:

int number1 = 10;
int number2 = number1;

number2 = 20;

Console.WriteLine(number1); // 10
Console.WriteLine(number2); // 20

赋值时会复制一份值,所以修改 number2 不会影响 number1

常见值类型包括:

int、long、float、double、decimal、bool、char、struct、enum

字符串、数组【7】、类等属于引用类型。变量中保存的是对象的引用:

int[] numbers1 = { 1, 2, 3 };
int[] numbers2 = numbers1;

numbers2[0] = 100;

Console.WriteLine(numbers1[0]); // 100

常见引用类型包括:

string、数组、class、interface、object、delegate

string 虽然是引用类型,但它具有不可变性,不能直接修改已有字符串的内容。

string name = "张";
name = name + "三"; // 实际上产生了一个新的字符串

3.命名规则

C# 变量名必须符合以下基本规则:

  • 可以使用字母、数字和下划线。
  • 不能以数字开头。
  • 不能包含空格以及 -+% 等符号。
  • 不能直接使用 C# 关键字。
  • C# 严格区分大小写。

二、常量

常量是一个在声明后不能再被修改的固定值。C# 中主要使用 const 声明编译期常量

1.基本语法

const【8】 数据类型 常量名称 = 常量值;

例如:

const int MaximumScore = 100;
const double Pi = 3.1415926;
const string DefaultName = "游客";
const bool IsDebugMode = false;

//常量必须在声明时赋值:

const int MaximumScore = 100; // 正确

// const int MinimumScore;    // 错误:没有初始化
// MinimumScore = 0;

//赋值后不能修改

const int MaximumScore = 100;

// MaximumScore = 200; // 编译错误

2.const的主要特点

1.必须在声明时初始化。2.初始化值必须能在编译期间确定。3.声明后不能重新赋值。4.可以声明为局部常量或类成员常量。5.类中的 const 成员隐式属于类本身,相当于静态成员。6.不能同时写成 static const

class MathSettings
{
    public const double Pi = 3.1415926;
}

double result = MathSettings.Pi * 10;

//下面写法错误:

// public static const double Pi = 3.14;

3.常用的常量类型

通常,以上变量类型都可作为常量定义,运行编译才可确定的数值,不可作为常量:

const byte Level = 10;
const int MaximumCount = 100;
const long Distance = 9_000_000_000L;

const float Rate = 0.5F;
const double Pi = 3.1415926;
const decimal TaxRate = 0.13M;

const char Separator = ',';
const string DefaultName = "游客";
const bool IsEnabled = true;

//枚举值也可以作为常量:
const ConsoleColor DefaultColor = ConsoleColor.Blue;
//常量表达式可以使用其他常量:
const int SecondsPerMinute = 60;
const int MinutesPerHour = 60;
const int SecondsPerHour = SecondsPerMinute * MinutesPerHour;

4.常量的作用域

局部常量只能在所在代码块中使用,类成员常量可以通过类名访问:

void Calculate()
{
    const double Pi = 3.1415926;
    double area = Pi * 10 * 10;
}

// 此处不能使用 Pi


class GameSettings
{
    public const int MaximumLevel = 100;
}

Console.WriteLine(GameSettings.MaximumLevel);

三、C# 转义字符

转义字符【9】用于表示一些不能直接输入,或者具有特殊含义的字符。它们通常以反斜杠 \ 开头。

1.常用转义字符

转义字符含义示例
\n换行"第一行\n第二行"
\r回车"内容\r"
\t水平制表符"姓名\t成绩"
\\反斜杠"C:\\Users\\Li"
\"双引号"他说:\"你好\""
\'单引号'\''
\0空字符,Unicode【10】 U+0000'\0'
\a警报、响铃"\a"
\b退格"ABC\b"
\f换页"\f"
\v垂直制表符"\v"
\eEscape 字符"\e",C# 13+

2.常见示例

换行:

string message = "姓名:张三\n年龄:18";
Console.WriteLine(message);

制表符:

Console.WriteLine("姓名\t成绩");
Console.WriteLine("张三\t100");
Console.WriteLine("李四\t90");

双引号:

string sentence = "老师说:\"请认真学习。\"";

反斜杠:

string path = "C:\\Users\\Li\\Documents";

单引号字符:

char singleQuote = '\'';

3.Unicode 转义字符

可以通过 Unicode 编码表示字符。

\u 后面必须跟四位十六进制数字:

char letter = '\u0041';       // A
char chinese = '\u4E2D';      // 中
string text = "\u4F60\u597D"; // 你好

\U 后面跟八位十六进制数字,可以表示 emoji 等较大的 Unicode 字符:

string emoji = "\U0001F600"; // 😀

\x 后面可以跟十六进制数字:

char letter = '\x41'; // A

由于 \x 使用的数字位数可能不固定,容易产生歧义,因此通常优先使用固定四位的 \u

4.逐字字符串 @与 原始字符串

在字符串前添加 @,反斜杠会按照普通字符处理,适合表示文件路径:

string path1 = "C:\\Users\\Li\\Documents";
string path2 = @"C:\Users\Li\Documents";

这两个字符串的内容相同。

逐字字符串【11】中的双引号需要写两次:

string text = @"老师说:""你好。""";

在逐字字符串中,\n 不会被解释为换行:

string text = @"第一行\n第二行";

Console.WriteLine(text);

输出:

第一行\n第二行

C# 11 开始支持三个双引号组成的原始字符串【12】,适合保存 JSON、HTML 等文本:

string json = """
{
    "name": "张三",
    "path": "C:\Users\Li"
}
""";

四、数据类型的转换

类型转换主要分为两类:隐式转换【13】显式转换【14】

1.隐式转换

范围较小的类型转换为范围较大的类型,编译器自动完成,通常不会丢失数据。

int damage = 10;
float finalDamage = damage;

int 转 float

int speed = 5;
float distance = speed * Time.deltaTime;

2. 显式转换

强制转换 (类型)

可能丢失数据,需要使用强制转换符:

float distance = 9.8f;
int value = (int)distance; // 9,直接截掉小数

Unity 中常用于坐标、时间或下标:

int x = (int)transform.position.x;
int second = (int)Time.time;

不能直接将字符串强转为整数:

// int level = (int)"10"; // 错误

Parse【15】

用于将字符串转换成指定类型:

int level = int.Parse("10");
float speed = float.Parse("5.5");
bool enabled = bool.Parse("true");

格式错误时会抛出异常,因此不适合直接处理玩家输入。可使用TryParse【16】替代:

if (int.TryParse(inputField.text, out int level))
{
    Debug.Log($"等级:{level}");
}
else
{
    Debug.LogWarning("请输入正确的数字");
}

// bool 是否成功 = 数据类型.TryParse(字符串, out 转换结果);

//其他类型:
float.TryParse("5.5", out float speed);
double.TryParse("3.14", out double pi);
bool.TryParse("true", out bool enabled);

Convert【18】

可以在字符串和常见基础类型之间转换:

int level = Convert.ToInt32("10");
float speed = Convert.ToSingle("5.5");
string text = Convert.ToString(100);

注意强转与 Convert 的区别:

int a = (int)3.8f;             // 3,截掉小数
int b = Convert.ToInt32(3.8f); // 4,四舍五入

五、C# 异常捕获

异常捕获【19】用于处理程序运行期间出现的错误,避免程序直接中断。

基本语法

try
{
    // 可能出现异常的代码
}
catch (Exception ex)
{
    // 出现异常后的处理
}
finally
{
    // 无论是否异常,通常都会执行
}

//示例

try
{
    int number = int.Parse("abc");
}
catch (Exception ex)
{
    Debug.LogError($"转换失败:{ex.Message}");
}

六、运算

运算可分为算数运算、逻辑运算【20】、位运算【21】几类。

1.算数运算符

运算符含义示例
+加法a + b
-减法a - b
*乘法a * b
/除法a / b
%取余a % b
++自增 1count++
--自减 1count--
int a = 10;
int b = 3;

Debug.Log(a + b); // 13
Debug.Log(a - b); // 7
Debug.Log(a * b); // 30
Debug.Log(a / b); // 3
Debug.Log(a % b); // 1

//整数相除会舍弃小数:

float result1 = 5 / 2;    // 2
float result2 = 5f / 2f;  // 2.5

//复合赋值运算符:

hp += 10; // hp = hp + 10
hp -= 10;
hp *= 2;
hp /= 2;
hp %= 3;

//++ 前置与后置:

int a = 10;

int b = a++; // b是10,然后a变成11
int c = ++a; // a先变成12,然后赋给c

Unity 常用数学方法:

Mathf.Abs(value);             // 绝对值
Mathf.Min(a, b);              // 最小值
Mathf.Max(a, b);              // 最大值
Mathf.Clamp(hp, 0, 100);      // 限制范围
Mathf.Pow(2, 3);              // 2的3次方
Mathf.Sqrt(16);               // 平方根
Mathf.RoundToInt(3.6f);       // 四舍五入
Mathf.FloorToInt(3.6f);       // 向下取整
Mathf.CeilToInt(3.1f);        // 向上取整
Mathf.Lerp(0, 100, 0.5f);     // 插值,结果50

随机数:

int number = Random.Range(0, 10);      // 0~9
float value = Random.Range(0f, 10f);   // 浮点范围

//复杂运算建议使用括号明确顺序:
float damage = (attack + weaponDamage) * multiplier; 若无括号则是先算乘除后算加减

2. 字符串拼接与打印

使用 + 拼接

string playerName = "张三";
int score = 100;

string message = "玩家:" + playerName + ",分数:" + score;

字符串插值

Unity 开发中推荐使用:

string message = $"玩家:{playerName},分数:{score}";

设置小数显示位数:

float time = 12.3456f;
Debug.Log($"时间:{time:F2}"); // 时间:12.35

其他拼接方法

string result1 = string.Concat("生命值:", hp);
string result2 = string.Join(", ", playerNames);
string result3 = string.Format("分数:{0}", score);
Console.WriteLine("分数:{0}", score); //格式化打印

打印方法

普通 C#:

Console.Write("不换行");
Console.WriteLine("打印后换行");

Unity:

Debug.Log("普通信息");
Debug.LogWarning("警告信息");
Debug.LogError("错误信息");
Debug.LogException(exception);

显示到 UI:

scoreText.text = $"分数:{score}";

字符串不可变。在 Update() 中频繁拼接和更新 UI 可能产生额外内存分配,最好只在数据改变时更新。

3. 条件运算符(比较运算符)

比较结果都是 bool 类型:

运算符含义
==等于
!=不等于
>大于
<小于
>=大于等于
<=小于等于
if (hp <= 0)
{
    Debug.Log("玩家死亡");
}

判断范围:

if (hp >= 0 && hp <= maxHp)
{
    Debug.Log("生命值正常");
}

浮点数可能存在精度误差,Unity 中推荐:

if (Mathf.Approximately(a, b))
{
    Debug.Log("两个浮点数近似相等");
}

字符串内容比较:

if (playerName == "张三")
{
}

忽略大小写:

bool same = string.Equals(
    input,
    "start",
    StringComparison.OrdinalIgnoreCase
);

4. 逻辑运算符

运算符含义
&&并且,全部为真才是真
`
!取反
^异或,两个条件不同时为真
if (hp > 0 && hasWeapon)
{
    Debug.Log("可以攻击");
}

if (isDead || isPaused)
{
    return;
}

if (!isGrounded)
{
    Debug.Log("角色在空中");
}

&&|| 具有短路功能:

if (player != null && player.Health > 0)
{
}

如果 playernull,后面的代码不会执行,因此不会访问空对象。

&| 也能用于布尔值,但不会短路,普通条件判断优先使用 &&||

5. 位运算符

位运算直接操作整数的二进制位:

运算符含义
&按位与
``
^按位异或
~按位取反
<<左移
>>右移
int a = 6; // 0110
int b = 3; // 0011

int andResult = a & b; // 0010,结果2
int orResult  = a | b; // 0111,结果7
int xorResult = a ^ b; // 0101,结果5

位移:

int a = 1 << 3; // 0001 左移3位,结果8
int b = 8 >> 2; // 1000 右移2位,结果2

Unity 中最常见的用途是 LayerMask

LayerMask targetMask = LayerMask.GetMask("Enemy", "Obstacle");

bool isIncluded =
    (targetMask.value & (1 << gameObject.layer)) != 0;

添加和移除某一位:

mask |= 1 << layer;       // 添加层
mask &= ~(1 << layer);    // 移除层

位运算通常用于层级遮罩、权限和状态标记,不用于普通小数。

6. 三目运算符

语法:

条件 ? 条件成立的值 : 条件不成立的值

示例:

string state = hp > 0 ? "存活" : "死亡";

等价于:

string state;

if (hp > 0)
{
    state = "存活";
}
else
{
    state = "死亡";
}

Unity 示例:

spriteRenderer.color = isHurt ? Color.red : Color.white;

三目运算符【22】适合简单的二选一。逻辑复杂时使用 if...else

七、三类逻辑

1. while 循环

只要条件成立,就不断执行:

int count = 0;

while (count < 3)
{
    Debug.Log(count);
    count++;
}

适合循环次数事先不确定的情况。

无限循环【23】

while (true)
{
    if (shouldStop)
    {
        break;
    }
}

Unity 主线程中不能执行无法及时结束的循环,否则游戏会卡死。跨帧等待应使用协程【24】

IEnumerator Countdown(float time)
{
    while (time > 0f)
    {
        time -= Time.deltaTime;
        yield return null;
    }

    Debug.Log("倒计时结束");
}

2. for 循环

语法:

for (初始化; 循环条件; 更新变量)
{
    // 循环体
}

示例:

for (int i = 0; i < 5; i++)
{
    Debug.Log(i);
}

遍历数组和列表【25】

for (int i = 0; i < enemies.Count; i++)
{
    enemies[i].TakeDamage(10);
}

删除列表元素时通常倒序遍历【26】

for (int i = enemies.Count - 1; i >= 0; i--)
{
    if (enemies[i] == null)
    {
        enemies.RemoveAt(i);
    }
}

数组使用 .Length,列表使用 .Count

array.Length;
list.Count;

3. do...while 循环

先执行一次,再判断条件,所以循环体至少执行一次:

int count = 0;

do
{
    Debug.Log(count);
    count++;
}
while (count < 3);

注意结尾有分号:

while (条件);

适用于必须先执行一次,再决定是否继续的逻辑。

4. switch

适合根据一个变量的不同值执行不同代码,Unity 中经常用于角色状态。

enum PlayerState
{
    Idle,
    Run,
    Jump
}
switch (playerState)
{
    case PlayerState.Idle:
        Debug.Log("待机");
        break;

    case PlayerState.Run:
        Debug.Log("奔跑");
        break;

    case PlayerState.Jump:
        Debug.Log("跳跃");
        break;

    default:
        Debug.LogWarning("未知状态");
        break;
}

多个情况执行相同逻辑:

switch (playerState)
{
    case PlayerState.Idle:
    case PlayerState.Run:
        Debug.Log("角色在地面");
        break;

    case PlayerState.Jump:
        Debug.Log("角色在空中");
        break;
}

较新的 C# 还可以使用 switch 表达式:

string animationName = playerState switch
{
    PlayerState.Idle => "Idle",
    PlayerState.Run  => "Run",
    PlayerState.Jump => "Jump",
    _                => "Unknown"
};

_ 相当于传统 switch 中的 default。是否支持取决于 Unity 项目使用的 C# 版本。

5. 循环控制关键字

break;    // 立即结束当前循环或switch
continue; // 跳过本次循环,进入下一次
return;   // 直接结束当前方法

示例:

for (int i = 0; i < enemies.Count; i++)
{
    if (enemies[i] == null)
    {
        continue;
    }

    if (enemies[i].IsBoss)
    {
        break;
    }

    enemies[i].TakeDamage(10);
}

补充:遍历集合还可以使用 foreach

foreach (Enemy enemy in enemies)
{
    enemy.TakeDamage(10);
}

foreach 遍历期间通常不能增加或删除集合元素;需要删除时使用倒序 for