基础语法详解

目录

02. 基础语法详解

C#基础语法完全指南 - 从C/C++到C#的语法对比学习


📌 本章导航


数据类型详解

值类型 (Value Types)

C#的值类型与C/C++有很多相似之处,但也有一些重要差异:

// 整数类型
sbyte  num1 = -128;    // 8位有符号整数 (-128 到 127)
byte   num2 = 255;     // 8位无符号整数 (0 到 255)
short  num3 = -32768;  // 16位有符号整数
ushort num4 = 65535;   // 16位无符号整数
int    num5 = -2147483648;  // 32位有符号整数 (与C++ int相同)
uint   num6 = 4294967295U;  // 32位无符号整数
long   num7 = 9223372036854775807L;  // 64位有符号整数
ulong  num8 = 18446744073709551615UL; // 64位无符号整数

// 浮点类型
float  f1 = 3.14F;     // 32位浮点数 (需要F后缀)
double f2 = 3.14159;   // 64位浮点数 (默认)
decimal f3 = 3.14159M; // 128位高精度浮点数 (需要M后缀)

// 布尔类型
bool   flag = true;    // 与C++ bool相同

// 字符类型
char   ch = 'A';       // 16位Unicode字符 (与C++ char不同)

与C/C++的主要差异:

C/C++ C# 说明
bool bool 相同
char (8位) char (16位) C#的char是Unicode
wchar_t char C#原生支持Unicode
无内置decimal decimal C#提供高精度小数类型

引用类型 (Reference Types)

// 字符串类型
string name = "Hello World";  // 与C++ string类似,但更安全
string multiline = @"这是一个
多行字符串
支持换行";

// 数组
int[] numbers = new int[5];           // 一维数组
int[,] matrix = new int[3, 3];        // 二维数组
int[][] jagged = new int[3][];        // 锯齿数组

// 对象
Player player = new Player();         // 创建对象

可空类型 (Nullable Types)

// C#特有的可空类型
int? nullableInt = null;              // 可空整数
bool? nullableBool = null;            // 可空布尔值

// 检查可空类型
if (nullableInt.HasValue)
{
    Console.WriteLine(nullableInt.Value);
}
else
{
    Console.WriteLine("值为null");
}

// 空合并运算符
int result = nullableInt ?? 0;        // 如果为null则使用默认值

变量和常量

变量声明

// 显式类型声明
int age = 25;
string name = "Alice";
bool isActive = true;

// 隐式类型声明 (var关键字)
var score = 100;           // 编译器推断为int
var playerName = "Bob";    // 编译器推断为string
var players = new List<string>(); // 编译器推断为List<string>

// 常量声明
const int MAX_PLAYERS = 10;        // 编译时常量
readonly double PI = 3.14159;      // 运行时常量

变量作用域

public class GameLogic
{
    // 字段 (类级别)
    private int gameScore = 0;
    
    // 局部变量
    public void UpdateScore(int points)
    {
        int tempScore = gameScore + points;  // 方法级别
        
        if (tempScore > 1000)
        {
            bool isHighScore = true;         // 块级别
            Console.WriteLine("高分!");
        }
        
        // isHighScore在此处不可访问
    }
}

字面量表示法

// 整数字面量
int binary = 0b1010;           // 二进制 (C# 7.0+)
int hex = 0xFF;                // 十六进制
int decimalNum = 123;          // 十进制
int largeNum = 1_000_000;     // 数字分隔符 (C# 7.0+)

// 字符串字面量
string normal = "Hello";
string verbatim = @"C:\Users\Game\Assets";  // 逐字字符串,不转义

// 字符字面量
char letter = 'A';
char escape = '\n';           // 转义字符
char unicode = 'A';      // Unicode字符 (A)

控制流语句

条件语句

// if-else语句 (与C++基本相同)
int playerLevel = 5;
if (playerLevel >= 10)
{
    Console.WriteLine("高级玩家");
}
else if (playerLevel >= 5)
{
    Console.WriteLine("中级玩家");
}
else
{
    Console.WriteLine("初级玩家");
}

// switch语句 (C#更强大)
string playerClass = "Warrior";
switch (playerClass)
{
    case "Warrior":
        Console.WriteLine("战士 - 高生命值");
        break;
    case "Mage":
        Console.WriteLine("法师 - 高魔法");
        break;
    case "Archer" when playerLevel > 5:  // 模式匹配 (C# 7.0+)
        Console.WriteLine("高级弓箭手");
        break;
    case "Archer":
        Console.WriteLine("弓箭手");
        break;
    default:
        Console.WriteLine("未知职业");
        break;
}

// 三元运算符
string status = playerLevel >= 10 ? "Expert" : "Beginner";

// 模式匹配 (C# 7.0+)
object value = 42;
if (value is int number && number > 0)
{
    Console.WriteLine($"正整数: {number}");
}

循环语句

// for循环 (与C++相同)
for (int i = 0; i < 10; i++)
{
    Console.WriteLine($"循环 {i}");
}

// while循环 (与C++相同)
int count = 0;
while (count < 5)
{
    Console.WriteLine($"计数: {count}");
    count++;
}

// do-while循环 (与C++相同)
int health = 100;
do
{
    health -= 10;
    Console.WriteLine($"生命值: {health}");
} while (health > 0);

// foreach循环 (C#特有,类似C++范围for)
string[] items = {"Sword", "Shield", "Potion"};
foreach (string item in items)
{
    Console.WriteLine($"物品: {item}");
}

// for-each with collections
List<int> scores = new List<int> {85, 92, 78, 96};
foreach (int score in scores)
{
    Console.WriteLine($"分数: {score}");
}

// using range-based for (C# 8.0+)
int[] numbers = {1, 2, 3, 4, 5};
foreach (int num in numbers)
{
    Console.WriteLine(num);
}

跳转语句

// break, continue, goto (与C++相同)
for (int i = 0; i < 10; i++)
{
    if (i == 3)
        continue;  // 跳过本次循环
    
    if (i == 8)
        break;     // 退出循环
    
    Console.WriteLine(i);
}

// return (与C++相同)
public int CalculateScore(int baseScore, bool isBonus)
{
    if (isBonus)
        return baseScore * 2;
    
    return baseScore;
}

方法定义和调用

基本方法定义

public class Player
{
    public string Name { get; set; }
    public int Level { get; set; } = 1;
    public int Health { get; set; } = 100;
    
    // 基本方法
    public void TakeDamage(int damage)
    {
        Health -= damage;
        if (Health <= 0)
        {
            Die();
        }
    }
    
    // 带返回值的方法
    public bool IsAlive()
    {
        return Health > 0;
    }
    
    // 静态方法
    public static int CalculateExperience(int currentLevel)
    {
        return currentLevel * 1000;
    }
    
    // 方法重载
    public void Move(int x, int y)
    {
        Console.WriteLine($"移动到 ({x}, {y})");
    }
    
    public void Move(Vector2 position)
    {
        Console.WriteLine($"移动到 {position}");
    }
    
    private void Die()
    {
        Console.WriteLine($"{Name} 死亡了!");
    }
}

方法参数

public class GameMath
{
    // 值参数 (默认)
    public static int Add(int a, int b)
    {
        return a + b;
    }
    
    // 输出参数 (类似C++的引用参数)
    public static void GetPlayerStats(out int level, out int health)
    {
        level = 10;
        health = 100;
    }
    
    // 引用参数 (类似C++的引用)
    public static void ModifyPlayer(ref int health)
    {
        health += 50;
    }
    
    // 可变参数 (类似C++的可变参数模板)
    public static int Sum(params int[] numbers)
    {
        int total = 0;
        foreach (int num in numbers)
        {
            total += num;
        }
        return total;
    }
    
    // 命名参数 (C#特有)
    public static void CreatePlayer(string name, int level = 1, int health = 100)
    {
        Console.WriteLine($"创建玩家: {name}, 等级: {level}, 生命: {health}");
    }
    
    // 可选参数 (C#特有)
    public static void Attack(string target, int damage = 10, bool isCritical = false)
    {
        Console.WriteLine($"攻击 {target} 造成 {damage} 点伤害");
        if (isCritical)
            Console.WriteLine("暴击!");
    }
}

// 使用示例
Player player = new Player();
GameMath.GetPlayerStats(out int level, out int health);  // 输出参数
GameMath.ModifyPlayer(ref health);                      // 引用参数
int sum = GameMath.Sum(1, 2, 3, 4, 5);                 // 可变参数
GameMath.CreatePlayer("Hero", health: 150);            // 命名参数
GameMath.Attack("Enemy");                              // 使用默认参数

Lambda表达式

using System;
using System.Collections.Generic;
using System.Linq;

// Lambda表达式 - C#强大的特性
public class GameFilter
{
    public void DemonstrateLambdas()
    {
        List<int> scores = new List<int> {85, 92, 78, 96, 88, 94};
        
        // 简单Lambda
        Func<int, bool> isHighScore = score => score > 90;
        var highScores = scores.Where(isHighScore);
        
        // 多参数Lambda
        Func<int, int, int> add = (a, b) => a + b;
        
        // 无参数Lambda
        Action printHello = () => Console.WriteLine("Hello");
        
        // 复杂Lambda
        var excellentScores = scores.Where(score => score >= 90)
                                   .OrderByDescending(score => score)
                                   .ToList();
        
        // 在Unity中使用Lambda
        List<Player> players = new List<Player>();
        var activePlayers = players.Where(p => p.Health > 0 && p.Level >= 5);
    }
}

参数传递机制

值传递 vs 引用传递

public class ParameterDemo
{
    // 值传递 (默认) - 传递副本
    public static void ChangeValue(int number)
    {
        number = 100;  // 只改变局部副本
    }
    
    // 引用传递 - 传递引用
    public static void ChangeValueRef(ref int number)
    {
        number = 100;  // 改变原始值
    }
    
    // 输出参数
    public static void GetValues(out int value1, out int value2)
    {
        value1 = 10;   // 必须赋值
        value2 = 20;   // 必须赋值
    }
    
    // 演示
    public static void Demo()
    {
        int num = 5;
        Console.WriteLine($"初始值: {num}");  // 5
        
        ChangeValue(num);
        Console.WriteLine($"值传递后: {num}");  // 5 (未改变)
        
        ChangeValueRef(ref num);
        Console.WriteLine($"引用传递后: {num}");  // 100 (已改变)
        
        GetValues(out int a, out int b);
        Console.WriteLine($"输出参数: {a}, {b}");  // 10, 20
    }
}

引用类型参数

public class ReferenceTypeDemo
{
    // 引用类型参数 - 传递引用的副本
    public static void ModifyList(List<int> list)
    {
        list.Add(999);        // 会修改原始列表
        list = new List<int> {1, 2, 3};  // 只改变局部引用,不影响原始列表
    }
    
    // 使用ref传递引用本身
    public static void ReplaceList(ref List<int> list)
    {
        list = new List<int> {1, 2, 3};  // 会替换原始列表
    }
    
    public static void Demo()
    {
        List<int> numbers = new List<int> {1, 2, 3};
        Console.WriteLine($"初始: [{string.Join(", ", numbers)}]");  // [1, 2, 3]
        
        ModifyList(numbers);
        Console.WriteLine($"修改后: [{string.Join(", ", numbers)}]");  // [1, 2, 3, 999]
        
        ReplaceList(ref numbers);
        Console.WriteLine($"替换后: [{string.Join(", ", numbers)}]");  // [1, 2, 3]
    }
}

类型转换

隐式转换

public class TypeConversion
{
    public static void ImplicitConversion()
    {
        // 数值类型隐式转换 (从小到大)
        byte b = 100;
        int i = b;        // byte -> int (安全)
        long l = i;       // int -> long (安全)
        float f = l;      // long -> float (可能精度损失)
        double d = f;     // float -> double (安全)
        
        // 引用类型隐式转换
        Player player = new Player();
        object obj = player;  // 派生类 -> 基类 (安全)
        
        // 值类型隐式转换
        int? nullableInt = 5;  // int -> int? (安全)
    }
}

显式转换

public class ExplicitConversion
{
    public static void ExplicitConversionDemo()
    {
        // 数值类型显式转换 (强制转换)
        int largeNum = 1000000;
        short smallNum = (short)largeNum;  // 可能数据丢失
        
        // 检查转换 (安全方式)
        if (largeNum <= short.MaxValue && largeNum >= short.MinValue)
        {
            smallNum = (short)largeNum;
        }
        
        // 使用Convert类 (更安全)
        try
        {
            short converted = Convert.ToInt16(largeNum);
        }
        catch (OverflowException)
        {
            Console.WriteLine("转换溢出!");
        }
        
        // 引用类型转换
        object obj = new Player();
        if (obj is Player player)
        {
            // 安全转换
            Console.WriteLine($"玩家: {player.Name}");
        }
        
        // as运算符 (失败返回null)
        Player player2 = obj as Player;
        if (player2 != null)
        {
            Console.WriteLine($"转换成功: {player2.Name}");
        }
        
        // is运算符 (类型检查)
        if (obj is Player)
        {
            Player p = (Player)obj;  // 安全转换
        }
    }
}

用户定义转换

public struct Vector2
{
    public float X { get; set; }
    public float Y { get; set; }
    
    public Vector2(float x, float y)
    {
        X = x;
        Y = y;
    }
    
    // 隐式转换
    public static implicit operator Vector2(Point point)
    {
        return new Vector2(point.X, point.Y);
    }
    
    // 显式转换
    public static explicit operator Point(Vector2 vector)
    {
        return new Point((int)vector.X, (int)vector.Y);
    }
    
    public override string ToString()
    {
        return $"({X}, {Y})";
    }
}

public struct Point
{
    public int X { get; set; }
    public int Y { get; set; }
    
    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }
}

// 使用示例
public class ConversionUsage
{
    public static void Demo()
    {
        Point point = new Point(10, 20);
        
        // 隐式转换
        Vector2 vector = point;  // 自动转换
        Console.WriteLine(vector);  // (10, 20)
        
        // 显式转换
        Point converted = (Point)vector;  // 需要显式转换
        Console.WriteLine($"({converted.X}, {converted.Y})");
    }
}

异常处理基础

try-catch-finally

using System;
using System.IO;

public class ExceptionHandling
{
    public static void BasicExceptionHandling()
    {
        try
        {
            // 可能抛出异常的代码
            int[] numbers = {1, 2, 3};
            int value = numbers[10];  // 索引超出范围
        }
        catch (IndexOutOfRangeException ex)
        {
            // 处理特定异常
            Console.WriteLine($"数组越界: {ex.Message}");
        }
        catch (Exception ex)
        {
            // 处理所有其他异常
            Console.WriteLine($"发生异常: {ex.Message}");
        }
        finally
        {
            // 无论是否发生异常都会执行
            Console.WriteLine("清理资源");
        }
    }
    
    // 多异常处理 (C# 6.0+)
    public static void MultipleExceptions()
    {
        try
        {
            // 一些操作
        }
        catch (FileNotFoundException)
        {
            Console.WriteLine("文件未找到");
        }
        catch (DirectoryNotFoundException)
        {
            Console.WriteLine("目录未找到");
        }
        catch (IOException ex) when (ex.Message.Contains("access"))
        {
            // 异常过滤器 (C# 7.0+)
            Console.WriteLine("访问权限问题");
        }
    }
    
    // 异常抛出
    public static void ThrowException(int level)
    {
        if (level < 1)
        {
            throw new ArgumentException("等级不能小于1", nameof(level));
        }
        
        if (level > 100)
        {
            throw new ArgumentOutOfRangeException(nameof(level), "等级不能超过100");
        }
    }
    
    // 自定义异常
    public class GameException : Exception
    {
        public GameException(string message) : base(message) { }
        public GameException(string message, Exception inner) : base(message, inner) { }
    }
    
    public static void UseCustomException()
    {
        try
        {
            throw new GameException("游戏错误");
        }
        catch (GameException ex)
        {
            Console.WriteLine($"游戏异常: {ex.Message}");
        }
    }
}

using语句 (资源管理)

using System;
using System.IO;

public class ResourceManagement
{
    // 传统的try-finally
    public static void TraditionalWay()
    {
        FileStream file = null;
        try
        {
            file = new FileStream("data.txt", FileMode.Open);
            // 使用文件
        }
        finally
        {
            file?.Dispose();  // 确保资源释放
        }
    }
    
    // using语句 (推荐)
    public static void UsingStatement()
    {
        using (FileStream file = new FileStream("data.txt", FileMode.Open))
        {
            // 使用文件
            // 离开using块时自动调用Dispose()
        }
    }
    
    // using声明 (C# 8.0+)
    public static void UsingDeclaration()
    {
        using FileStream file = new FileStream("data.txt", FileMode.Open);
        // 文件在方法结束时自动释放
    }
    
    // 多个资源
    public static void MultipleResources()
    {
        using (FileStream input = new FileStream("input.txt", FileMode.Open))
        using (FileStream output = new FileStream("output.txt", FileMode.Create))
        {
            // 同时使用多个资源
        }
    }
}

C#与C/C++语法差异总结

1. 内存管理

C/C++:

// 手动管理内存
Player* player = new Player();
// 必须手动delete
delete player;
player = nullptr;

C#:

// 自动垃圾回收
Player player = new Player();
// 无需手动释放,GC自动管理

2. 指针 vs 引用

C/C++:

int value = 10;
int* ptr = &value;  // 指针
*ptr = 20;          // 解引用

C#:

int value = 10;
// C#避免使用指针,更安全
int refValue = value;  // 值类型是值传递
// 如果需要引用语义,使用ref参数

3. 字符串处理

C/C++:

#include <string>
std::string name = "Hello";
name += " World";  // 拼接

C#:

string name = "Hello";
name += " World";  // 拼接
string formatted = $"Hello {name}!";  // 字符串插值 (更强大)

4. 数组声明

C/C++:

int arr[5] = {1, 2, 3, 4, 5};  // 栈上数组
int* arr2 = new int[5];         // 堆上数组

C#:

int[] arr = {1, 2, 3, 4, 5};    // 引用类型
int[] arr2 = new int[5];        // 创建指定大小

5. 函数指针 vs 委托

C/C++:

int (*func)(int, int) = &add;   // 函数指针

C#:

Func<int, int, int> func = (a, b) => a + b;  // 委托
Action<string> print = Console.WriteLine;     // 无返回值委托

实践练习

练习1: 游戏数据管理器

using System;
using System.Collections.Generic;

public class GameDataManager
{
    private Dictionary<string, object> _gameData = new Dictionary<string, object>();
    
    // 设置数据
    public void SetData<T>(string key, T value)
    {
        _gameData[key] = value;
    }
    
    // 获取数据
    public T GetData<T>(string key, T defaultValue = default(T))
    {
        if (_gameData.TryGetValue(key, out object value))
        {
            if (value is T result)
            {
                return result;
            }
            
            // 尝试转换
            try
            {
                return (T)Convert.ChangeType(value, typeof(T));
            }
            catch
            {
                return defaultValue;
            }
        }
        
        return defaultValue;
    }
    
    // 检查数据是否存在
    public bool HasData(string key)
    {
        return _gameData.ContainsKey(key);
    }
    
    // 删除数据
    public bool RemoveData(string key)
    {
        return _gameData.Remove(key);
    }
    
    // 清空所有数据
    public void ClearAll()
    {
        _gameData.Clear();
    }
    
    // 获取所有键
    public List<string> GetAllKeys()
    {
        return new List<string>(_gameData.Keys);
    }
}

// 使用示例
public class PracticeDemo
{
    public static void Run()
    {
        GameDataManager manager = new GameDataManager();
        
        // 存储不同类型的数据
        manager.SetData("playerName", "Hero");
        manager.SetData("playerLevel", 10);
        manager.SetData("playerHealth", 100.5f);
        manager.SetData("isOnline", true);
        
        // 读取数据
        string name = manager.GetData<string>("playerName");
        int level = manager.GetData<int>("playerLevel");
        float health = manager.GetData<float>("playerHealth");
        bool online = manager.GetData<bool>("isOnline");
        
        Console.WriteLine($"玩家: {name}, 等级: {level}, 生命: {health}, 在线: {online}");
        
        // 使用默认值
        int score = manager.GetData<int>("playerScore", 0);
        Console.WriteLine($"分数: {score}");  // 输出: 分数: 0
    }
}

练习2: 简单的游戏状态机

using System;

public enum GameState
{
    Menu,
    Playing,
    Paused,
    GameOver
}

public class SimpleGameStateMachine
{
    private GameState _currentState = GameState.Menu;
    
    public GameState CurrentState 
    { 
        get { return _currentState; }
        private set { _currentState = value; }
    }
    
    public void ChangeState(GameState newState)
    {
        if (newState == _currentState)
        {
            Console.WriteLine("已经在该状态");
            return;
        }
        
        GameState oldState = _currentState;
        _currentState = newState;
        
        OnStateExit(oldState);
        OnStateEnter(newState);
    }
    
    private void OnStateEnter(GameState state)
    {
        switch (state)
        {
            case GameState.Menu:
                Console.WriteLine("进入主菜单");
                break;
            case GameState.Playing:
                Console.WriteLine("开始游戏");
                break;
            case GameState.Paused:
                Console.WriteLine("游戏暂停");
                break;
            case GameState.GameOver:
                Console.WriteLine("游戏结束");
                break;
        }
    }
    
    private void OnStateExit(GameState state)
    {
        switch (state)
        {
            case GameState.Menu:
                Console.WriteLine("离开主菜单");
                break;
            case GameState.Playing:
                Console.WriteLine("停止游戏");
                break;
            case GameState.Paused:
                Console.WriteLine("恢复游戏");
                break;
            case GameState.GameOver:
                Console.WriteLine("结束游戏结束状态");
                break;
        }
    }
    
    // 状态转换验证
    public bool CanTransitionTo(GameState targetState)
    {
        switch (_currentState)
        {
            case GameState.Menu:
                return targetState == GameState.Playing;
            case GameState.Playing:
                return targetState == GameState.Paused || targetState == GameState.GameOver;
            case GameState.Paused:
                return targetState == GameState.Playing || targetState == GameState.Menu;
            case GameState.GameOver:
                return targetState == GameState.Menu;
            default:
                return false;
        }
    }
    
    public void HandleInput(string input)
    {
        switch (input.ToLower())
        {
            case "start":
                if (CanTransitionTo(GameState.Playing))
                    ChangeState(GameState.Playing);
                break;
            case "pause":
                if (CanTransitionTo(GameState.Paused))
                    ChangeState(GameState.Paused);
                break;
            case "resume":
                if (CanTransitionTo(GameState.Playing))
                    ChangeState(GameState.Playing);
                break;
            case "menu":
                if (CanTransitionTo(GameState.Menu))
                    ChangeState(GameState.Menu);
                break;
            case "gameover":
                if (CanTransitionTo(GameState.GameOver))
                    ChangeState(GameState.GameOver);
                break;
        }
    }
}

// 使用示例
public class StateMachineDemo
{
    public static void Run()
    {
        SimpleGameStateMachine stateMachine = new SimpleGameStateMachine();
        
        Console.WriteLine($"当前状态: {stateMachine.CurrentState}");
        
        stateMachine.HandleInput("start");
        Console.WriteLine($"当前状态: {stateMachine.CurrentState}");
        
        stateMachine.HandleInput("pause");
        Console.WriteLine($"当前状态: {stateMachine.CurrentState}");
        
        stateMachine.HandleInput("resume");
        Console.WriteLine($"当前状态: {stateMachine.CurrentState}");
        
        stateMachine.HandleInput("gameover");
        Console.WriteLine($"当前状态: {stateMachine.CurrentState}");
    }
}

常见错误和最佳实践

1. 避免装箱/拆箱性能问题

// 错误: 频繁的装箱拆箱
List<object> numbers = new List<object>();
for (int i = 0; i < 1000000; i++)
{
    numbers.Add(i);  // 装箱
    int value = (int)numbers[i];  // 拆箱
}

// 正确: 使用泛型
List<int> numbers = new List<int>();
for (int i = 0; i < 1000000; i++)
{
    numbers.Add(i);  // 无需装箱
    int value = numbers[i];  // 无需拆箱
}

2. 字符串拼接优化

// 错误: 低效的字符串拼接
string result = "";
for (int i = 0; i < 1000; i++)
{
    result += "Item " + i + ", ";  // 每次都创建新字符串
}

// 正确: 使用StringBuilder
using System.Text;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++)
{
    sb.Append("Item ");
    sb.Append(i);
    sb.Append(", ");
}
string result = sb.ToString();

// 或者使用字符串插值 (C# 6.0+)
string result = string.Join(", ", Enumerable.Range(0, 1000).Select(i => $"Item {i}"));

3. 正确使用异常

// 错误: 用异常控制流程
public int GetPlayerScore(string playerName)
{
    try
    {
        return playerScores[playerName];
    }
    catch (KeyNotFoundException)
    {
        return 0;  // 不应该用异常来处理正常流程
    }
}

// 正确: 使用Try模式
public bool TryGetPlayerScore(string playerName, out int score)
{
    return playerScores.TryGetValue(playerName, out score);
}

// 使用
if (TryGetPlayerScore("player1", out int score))
{
    Console.WriteLine($"分数: {score}");
}
else
{
    Console.WriteLine("玩家不存在");
}

总结

本章我们学习了C#的基础语法,包括:

数据类型: 值类型、引用类型、可空类型
变量和常量: 声明、作用域、字面量
控制流: if/switch/循环语句
方法: 定义、参数传递、Lambda表达式
类型转换: 隐式/显式转换
异常处理: try-catch-finally

这些基础知识是C#游戏开发的根基。与C/C++相比,C#提供了更安全的内存管理、更丰富的类型系统和更简洁的语法。


下一步

继续学习 03. 面向对象编程