1. C# 程序结构

1.1 基本程序结构

// 使用指令 - 导入命名空间
using System;
using System.Collections.Generic;
using System.Linq;

// 命名空间声明
namespace MyApplication
{
    // 类声明
    public class Program
    {
        // 程序入口点
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
        }
    }
    
    // 其他类
    public class MyClass
    {
        // 字段
        private int _value;
        
        // 属性
        public string Name { get; set; }
        
        // 方法
        public void DoSomething()
        {
            Console.WriteLine("Doing something...");
        }
    }
}

1.2 C# 9.0+ 顶级程序

// Program.cs - 简化的程序结构
using System;

// 直接编写代码,无需 Main 方法
Console.WriteLine("Hello, World!");

var name = "C#";
Console.WriteLine($"Welcome to {name} programming!");

// 可以定义本地函数
int Add(int a, int b) => a + b;

Console.WriteLine($"5 + 3 = {Add(5, 3)}");

// 可以定义类
public class Calculator
{
    public int Multiply(int a, int b) => a * b;
}

var calc = new Calculator();
Console.WriteLine($"4 * 6 = {calc.Multiply(4, 6)}");

1.3 命名空间和 using 指令

// 传统 using 指令
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

// C# 10.0 全局 using(在一个文件中声明)
// GlobalUsings.cs
global using System;
global using System.Collections.Generic;
global using System.Linq;

// C# 10.0 文件范围命名空间
namespace MyApplication.Services;

public class UserService
{
    public void GetUser(int id)
    {
        // 实现代码
    }
}

// using 别名
using Json = System.Text.Json;
using File = System.IO.File;

public class Example
{
    public void UseAliases()
    {
        var options = new Json.JsonSerializerOptions();
        var content = File.ReadAllText("data.json");
    }
}

2. 数据类型

2.1 值类型 (Value Types)

整数类型

using System;

public class IntegerTypes
{
    public static void Main()
    {
        // 有符号整数
        sbyte sbyteValue = -128;        // 8位,-128 到 127
        short shortValue = -32768;      // 16位,-32,768 到 32,767
        int intValue = -2147483648;     // 32位,-2,147,483,648 到 2,147,483,647
        long longValue = -9223372036854775808L; // 64位
        
        // 无符号整数
        byte byteValue = 255;           // 8位,0 到 255
        ushort ushortValue = 65535;     // 16位,0 到 65,535
        uint uintValue = 4294967295U;   // 32位,0 到 4,294,967,295
        ulong ulongValue = 18446744073709551615UL; // 64位
        
        // 显示类型信息
        Console.WriteLine($"int: {sizeof(int)} bytes, Min: {int.MinValue}, Max: {int.MaxValue}");
        Console.WriteLine($"long: {sizeof(long)} bytes, Min: {long.MinValue}, Max: {long.MaxValue}");
        
        // 数字分隔符 (C# 7.0+)
        int million = 1_000_000;
        long billion = 1_000_000_000L;
        
        // 不同进制表示
        int decimal_value = 42;         // 十进制
        int hex_value = 0x2A;          // 十六进制
        int binary_value = 0b101010;   // 二进制 (C# 7.0+)
        
        Console.WriteLine($"Decimal: {decimal_value}, Hex: {hex_value}, Binary: {binary_value}");
    }
}

浮点类型

using System;

public class FloatingPointTypes
{
    public static void Main()
    {
        // 单精度浮点数
        float floatValue = 3.14159f;    // 32位,约7位精度
        
        // 双精度浮点数
        double doubleValue = 3.141592653589793; // 64位,约15-17位精度
        
        // 高精度十进制
        decimal decimalValue = 3.141592653589793238462643383279m; // 128位,28-29位精度
        
        Console.WriteLine($"float: {floatValue} (精度: {sizeof(float)} bytes)");
        Console.WriteLine($"double: {doubleValue} (精度: {sizeof(double)} bytes)");
        Console.WriteLine($"decimal: {decimalValue} (精度: {sizeof(decimal)} bytes)");
        
        // 特殊值
        double positiveInfinity = double.PositiveInfinity;
        double negativeInfinity = double.NegativeInfinity;
        double notANumber = double.NaN;
        
        Console.WriteLine($"正无穷: {positiveInfinity}");
        Console.WriteLine($"负无穷: {negativeInfinity}");
        Console.WriteLine($"非数字: {notANumber}");
        
        // 检查特殊值
        Console.WriteLine($"是否为无穷: {double.IsInfinity(positiveInfinity)}");
        Console.WriteLine($"是否为NaN: {double.IsNaN(notANumber)}");
        
        // 精度比较
        DemonstratePrecision();
    }
    
    private static void DemonstratePrecision()
    {
        Console.WriteLine("\n精度演示:");
        
        float f1 = 0.1f + 0.2f;
        double d1 = 0.1 + 0.2;
        decimal m1 = 0.1m + 0.2m;
        
        Console.WriteLine($"float: 0.1 + 0.2 = {f1}");
        Console.WriteLine($"double: 0.1 + 0.2 = {d1}");
        Console.WriteLine($"decimal: 0.1 + 0.2 = {m1}");
        
        // 金融计算应使用 decimal
        decimal price = 19.95m;
        decimal tax = 0.08m;
        decimal total = price * (1 + tax);
        Console.WriteLine($"价格计算: {price} * (1 + {tax}) = {total:C}");
    }
}

字符和布尔类型

using System;

public class CharAndBoolTypes
{
    public static void Main()
    {
        // 字符类型
        char letter = 'A';
        char unicode = '\u0041';        // Unicode A
        char escape = '\n';            // 转义字符
        char chinese = '中';
        
        Console.WriteLine($"字符: {letter}, Unicode: {unicode}, 中文: {chinese}");
        Console.WriteLine($"字符的数值: {(int)letter}");
        
        // 转义字符
        string escapeChars = "换行:\n制表符:\t反斜杠:\\引号:\"");
        Console.WriteLine(escapeChars);
        
        // 布尔类型
        bool isTrue = true;
        bool isFalse = false;
        bool result = 5 > 3;
        
        Console.WriteLine($"布尔值: {isTrue}, {isFalse}, {result}");
        
        // 布尔运算
        bool and = true && false;      // 逻辑与
        bool or = true || false;       // 逻辑或
        bool not = !true;              // 逻辑非
        bool xor = true ^ false;       // 异或
        
        Console.WriteLine($"逻辑运算: AND={and}, OR={or}, NOT={not}, XOR={xor}");
    }
}

2.2 引用类型 (Reference Types)

字符串类型

using System;
using System.Text;

public class StringTypes
{
    public static void Main()
    {
        // 字符串声明
        string str1 = "Hello";
        string str2 = "World";
        string str3 = null;
        
        // 字符串连接
        string concatenated = str1 + " " + str2;
        string interpolated = $"{str1} {str2}!";  // 字符串插值
        string formatted = string.Format("{0} {1}!", str1, str2);
        
        Console.WriteLine($"连接: {concatenated}");
        Console.WriteLine($"插值: {interpolated}");
        Console.WriteLine($"格式化: {formatted}");
        
        // 逐字字符串
        string path1 = "C:\\Users\\Name\\Documents";
        string path2 = @"C:\Users\Name\Documents";  // 逐字字符串
        
        Console.WriteLine($"转义路径: {path1}");
        Console.WriteLine($"逐字路径: {path2}");
        
        // C# 11.0 原始字符串字面量
        string json = """
            {
                "name": "John",
                "age": 30,
                "city": "New York"
            }
            """;
        Console.WriteLine($"JSON:\n{json}");
        
        // 字符串方法
        DemonstrateStringMethods();
        
        // 字符串性能
        DemonstrateStringPerformance();
    }
    
    private static void DemonstrateStringMethods()
    {
        Console.WriteLine("\n字符串方法演示:");
        
        string text = "  Hello, World!  ";
        
        Console.WriteLine($"原始: '{text}'");
        Console.WriteLine($"长度: {text.Length}");
        Console.WriteLine($"去空格: '{text.Trim()}'");
        Console.WriteLine($"大写: {text.ToUpper()}");
        Console.WriteLine($"小写: {text.ToLower()}");
        Console.WriteLine($"包含'World': {text.Contains("World")}");
        Console.WriteLine($"开始于'  Hello': {text.StartsWith("  Hello")}");
        Console.WriteLine($"结束于'!  ': {text.EndsWith("!  ")}");
        Console.WriteLine($"索引'World': {text.IndexOf("World")}");
        Console.WriteLine($"子字符串(7,5): '{text.Substring(7, 5)}'");
        Console.WriteLine($"替换'World'->'C#': '{text.Replace("World", "C#")}'")
        
        // 字符串分割和连接
        string csv = "apple,banana,orange,grape";
        string[] fruits = csv.Split(',');
        Console.WriteLine($"分割: [{string.Join(", ", fruits)}]");
        
        string rejoined = string.Join(" | ", fruits);
        Console.WriteLine($"重新连接: {rejoined}");
    }
    
    private static void DemonstrateStringPerformance()
    {
        Console.WriteLine("\n字符串性能演示:");
        
        // 低效的字符串连接
        var stopwatch = System.Diagnostics.Stopwatch.StartNew();
        string result1 = "";
        for (int i = 0; i < 1000; i++)
        {
            result1 += i.ToString();
        }
        stopwatch.Stop();
        Console.WriteLine($"字符串连接耗时: {stopwatch.ElapsedMilliseconds} ms");
        
        // 高效的 StringBuilder
        stopwatch.Restart();
        var sb = new StringBuilder();
        for (int i = 0; i < 1000; i++)
        {
            sb.Append(i.ToString());
        }
        string result2 = sb.ToString();
        stopwatch.Stop();
        Console.WriteLine($"StringBuilder耗时: {stopwatch.ElapsedMilliseconds} ms");
        
        // 字符串驻留
        string a = "Hello";
        string b = "Hello";
        string c = new string("Hello".ToCharArray());
        
        Console.WriteLine($"引用相等 a==b: {ReferenceEquals(a, b)}");
        Console.WriteLine($"引用相等 a==c: {ReferenceEquals(a, c)}");
        Console.WriteLine($"值相等 a.Equals(c): {a.Equals(c)}");
    }
}

数组类型

using System;
using System.Linq;

public class ArrayTypes
{
    public static void Main()
    {
        // 一维数组
        int[] numbers = new int[5];              // 声明并分配
        int[] values = { 1, 2, 3, 4, 5 };       // 声明并初始化
        int[] scores = new int[] { 85, 92, 78, 96, 88 }; // 完整语法
        
        // 数组访问
        Console.WriteLine($"第一个元素: {values[0]}");
        Console.WriteLine($"最后一个元素: {values[values.Length - 1]}");
        Console.WriteLine($"数组长度: {values.Length}");
        
        // 数组遍历
        Console.WriteLine("使用 for 循环:");
        for (int i = 0; i < values.Length; i++)
        {
            Console.WriteLine($"values[{i}] = {values[i]}");
        }
        
        Console.WriteLine("使用 foreach 循环:");
        foreach (int value in values)
        {
            Console.WriteLine($"值: {value}");
        }
        
        // 多维数组
        DemonstrateMultidimensionalArrays();
        
        // 锯齿数组
        DemonstrateJaggedArrays();
        
        // 数组方法
        DemonstrateArrayMethods();
    }
    
    private static void DemonstrateMultidimensionalArrays()
    {
        Console.WriteLine("\n多维数组演示:");
        
        // 二维数组
        int[,] matrix = new int[3, 4];
        int[,] grid = {
            { 1, 2, 3, 4 },
            { 5, 6, 7, 8 },
            { 9, 10, 11, 12 }
        };
        
        Console.WriteLine($"矩阵维度: {grid.GetLength(0)} x {grid.GetLength(1)}");
        
        // 遍历二维数组
        for (int i = 0; i < grid.GetLength(0); i++)
        {
            for (int j = 0; j < grid.GetLength(1); j++)
            {
                Console.Write($"{grid[i, j],3} ");
            }
            Console.WriteLine();
        }
        
        // 三维数组
        int[,,] cube = new int[2, 3, 4];
        Console.WriteLine($"立方体维度: {cube.GetLength(0)} x {cube.GetLength(1)} x {cube.GetLength(2)}");
    }
    
    private static void DemonstrateJaggedArrays()
    {
        Console.WriteLine("\n锯齿数组演示:");
        
        // 锯齿数组(数组的数组)
        int[][] jaggedArray = new int[3][];
        jaggedArray[0] = new int[] { 1, 2 };
        jaggedArray[1] = new int[] { 3, 4, 5, 6 };
        jaggedArray[2] = new int[] { 7, 8, 9 };
        
        // 或者直接初始化
        int[][] jagged = {
            new int[] { 1, 2 },
            new int[] { 3, 4, 5, 6 },
            new int[] { 7, 8, 9 }
        };
        
        Console.WriteLine("锯齿数组内容:");
        for (int i = 0; i < jagged.Length; i++)
        {
            Console.Write($"行 {i}: ");
            for (int j = 0; j < jagged[i].Length; j++)
            {
                Console.Write($"{jagged[i][j]} ");
            }
            Console.WriteLine();
        }
    }
    
    private static void DemonstrateArrayMethods()
    {
        Console.WriteLine("\n数组方法演示:");
        
        int[] numbers = { 64, 34, 25, 12, 22, 11, 90 };
        
        Console.WriteLine($"原始数组: [{string.Join(", ", numbers)}]");
        
        // 排序
        int[] sorted = (int[])numbers.Clone();
        Array.Sort(sorted);
        Console.WriteLine($"排序后: [{string.Join(", ", sorted)}]");
        
        // 反转
        int[] reversed = (int[])sorted.Clone();
        Array.Reverse(reversed);
        Console.WriteLine($"反转后: [{string.Join(", ", reversed)}]");
        
        // 查找
        int index = Array.IndexOf(numbers, 25);
        Console.WriteLine($"25的索引: {index}");
        
        bool contains = Array.Exists(numbers, x => x > 50);
        Console.WriteLine($"包含大于50的数: {contains}");
        
        // LINQ 方法(需要 using System.Linq)
        var evenNumbers = numbers.Where(x => x % 2 == 0).ToArray();
        Console.WriteLine($"偶数: [{string.Join(", ", evenNumbers)}]");
        
        var sum = numbers.Sum();
        var average = numbers.Average();
        var max = numbers.Max();
        var min = numbers.Min();
        
        Console.WriteLine($"统计: 和={sum}, 平均={average:F2}, 最大={max}, 最小={min}");
    }
}

2.3 可空类型 (Nullable Types)

using System;

public class NullableTypes
{
    public static void Main()
    {
        // 可空值类型 (C# 2.0+)
        int? nullableInt = null;
        double? nullableDouble = 3.14;
        bool? nullableBool = true;
        
        Console.WriteLine($"可空整数: {nullableInt}");
        Console.WriteLine($"可空双精度: {nullableDouble}");
        Console.WriteLine($"可空布尔: {nullableBool}");
        
        // 检查是否有值
        if (nullableInt.HasValue)
        {
            Console.WriteLine($"nullableInt 的值: {nullableInt.Value}");
        }
        else
        {
            Console.WriteLine("nullableInt 为 null");
        }
        
        // 空合并操作符
        int value1 = nullableInt ?? 0;  // 如果为 null,使用默认值 0
        Console.WriteLine($"使用空合并操作符: {value1}");
        
        // 空合并赋值操作符 (C# 8.0+)
        nullableInt ??= 42;  // 如果为 null,则赋值为 42
        Console.WriteLine($"空合并赋值后: {nullableInt}");
        
        // 可空引用类型 (C# 8.0+)
        DemonstrateNullableReferenceTypes();
        
        // 空条件操作符
        DemonstrateNullConditionalOperators();
    }
    
    private static void DemonstrateNullableReferenceTypes()
    {
        Console.WriteLine("\n可空引用类型演示:");
        
        // 启用可空引用类型后
        string? nullableString = null;     // 可以为 null
        string nonNullableString = "Hello"; // 不应为 null
        
        // 编译器警告:可能的 null 引用
        // int length = nullableString.Length; // 警告!
        
        // 安全访问
        int? length = nullableString?.Length;
        Console.WriteLine($"字符串长度: {length}");
        
        // null 检查
        if (nullableString is not null)
        {
            Console.WriteLine($"字符串: {nullableString}");
        }
        
        // 空断言操作符 (!) - 告诉编译器这里不会为 null
        string definitelyNotNull = GetStringThatIsNeverNull();
        int definiteLength = definitelyNotNull!.Length; // 使用 ! 断言非 null
    }
    
    private static void DemonstrateNullConditionalOperators()
    {
        Console.WriteLine("\n空条件操作符演示:");
        
        Person? person = null;
        
        // 空条件成员访问
        string? name = person?.Name;
        Console.WriteLine($"姓名: {name}");
        
        // 空条件索引访问
        int[]? numbers = null;
        int? firstNumber = numbers?[0];
        Console.WriteLine($"第一个数字: {firstNumber}");
        
        // 链式空条件访问
        person = new Person { Name = "John", Address = new Address { City = "New York" } };
        string? city = person?.Address?.City;
        Console.WriteLine($"城市: {city}");
        
        // 空条件方法调用
        person?.PrintInfo();
        
        // 空条件委托调用
        Action? action = null;
        action?.Invoke(); // 如果不为 null 才调用
    }
    
    private static string GetStringThatIsNeverNull()
    {
        return "This is never null";
    }
}

public class Person
{
    public string? Name { get; set; }
    public Address? Address { get; set; }
    
    public void PrintInfo()
    {
        Console.WriteLine($"Person: {Name}");
    }
}

public class Address
{
    public string? City { get; set; }
    public string? Street { get; set; }
}

2.4 var 关键字和类型推断

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

public class TypeInference
{
    public static void Main()
    {
        // var 关键字 - 编译时类型推断
        var number = 42;           // 推断为 int
        var text = "Hello";        // 推断为 string
        var price = 19.99m;        // 推断为 decimal
        var isValid = true;        // 推断为 bool
        
        Console.WriteLine($"number 类型: {number.GetType()}");
        Console.WriteLine($"text 类型: {text.GetType()}");
        Console.WriteLine($"price 类型: {price.GetType()}");
        Console.WriteLine($"isValid 类型: {isValid.GetType()}");
        
        // 复杂类型推断
        var numbers = new List<int> { 1, 2, 3, 4, 5 };
        var dictionary = new Dictionary<string, int>
        {
            { "one", 1 },
            { "two", 2 },
            { "three", 3 }
        };
        
        Console.WriteLine($"numbers 类型: {numbers.GetType()}");
        Console.WriteLine($"dictionary 类型: {dictionary.GetType()}");
        
        // LINQ 查询中的 var
        var evenNumbers = numbers.Where(n => n % 2 == 0).ToList();
        Console.WriteLine($"evenNumbers 类型: {evenNumbers.GetType()}");
        
        // 匿名类型(必须使用 var)
        var person = new { Name = "John", Age = 30, City = "New York" };
        Console.WriteLine($"匿名类型: {person.GetType()}");
        Console.WriteLine($"Person: {person.Name}, {person.Age}, {person.City}");
        
        // var 的限制
        DemonstrateVarLimitations();
    }
    
    private static void DemonstrateVarLimitations()
    {
        Console.WriteLine("\nvar 关键字限制:");
        
        // 以下用法是错误的:
        // var x;                    // 错误:必须初始化
        // var y = null;             // 错误:无法推断类型
        // var z = { 1, 2, 3 };      // 错误:无法推断集合类型
        
        // 正确的用法:
        var validArray = new[] { 1, 2, 3 };  // 推断为 int[]
        var validList = new List<string>();   // 推断为 List<string>
        
        // 显式类型 vs var
        List<string> explicitList = new List<string>();  // 显式类型
        var implicitList = new List<string>();           // 隐式类型
        
        // 两者是等价的
        Console.WriteLine($"类型相同: {explicitList.GetType() == implicitList.GetType()}");
        
        // 何时使用 var
        Console.WriteLine("\n何时使用 var:");
        Console.WriteLine("1. 类型名很长或复杂时");
        Console.WriteLine("2. 匿名类型(必须使用)");
        Console.WriteLine("3. LINQ 查询结果");
        Console.WriteLine("4. 类型显而易见时");
        
        // 示例:复杂类型名
        Dictionary<string, List<Tuple<int, string>>> complexType = 
            new Dictionary<string, List<Tuple<int, string>>>();
        
        var simplifiedType = new Dictionary<string, List<Tuple<int, string>>>();
        
        Console.WriteLine("复杂类型使用 var 更简洁");
    }
}

3. 常量和字面量

3.1 常量声明

using System;

public class Constants
{
    // 编译时常量
    public const int MaxValue = 100;
    public const string ApplicationName = "MyApp";
    public const double Pi = 3.14159265359;
    
    // 只读字段(运行时常量)
    public static readonly DateTime StartTime = DateTime.Now;
    public static readonly string MachineName = Environment.MachineName;
    
    public static void Main()
    {
        Console.WriteLine($"最大值: {MaxValue}");
        Console.WriteLine($"应用名称: {ApplicationName}");
        Console.WriteLine($"圆周率: {Pi}");
        Console.WriteLine($"启动时间: {StartTime}");
        Console.WriteLine($"机器名: {MachineName}");
        
        // 局部常量
        const int localConstant = 42;
        Console.WriteLine($"局部常量: {localConstant}");
        
        // 常量表达式
        const int result = MaxValue * 2 + 10;
        Console.WriteLine($"常量表达式结果: {result}");
        
        // 演示 const vs readonly
        DemonstrateConstVsReadonly();
    }
    
    private static void DemonstrateConstVsReadonly()
    {
        Console.WriteLine("\nconst vs readonly 区别:");
        
        // const: 编译时确定,值嵌入到调用代码中
        Console.WriteLine($"const MaxValue: {MaxValue}");
        
        // readonly: 运行时确定,可以在构造函数中赋值
        Console.WriteLine($"readonly StartTime: {StartTime}");
        
        // const 只能是编译时常量
        // const DateTime CompileTimeError = DateTime.Now; // 错误!
        
        // readonly 可以是运行时值
        // readonly DateTime RuntimeValue = DateTime.Now; // 正确
    }
}

3.2 字面量

using System;

public class Literals
{
    public static void Main()
    {
        // 整数字面量
        int decimal_lit = 42;           // 十进制
        int hex_lit = 0x2A;            // 十六进制
        int binary_lit = 0b101010;     // 二进制 (C# 7.0+)
        
        // 长整数字面量
        long long_lit = 42L;
        ulong ulong_lit = 42UL;
        
        // 浮点字面量
        float float_lit = 3.14f;
        double double_lit = 3.14;
        decimal decimal_lit = 3.14m;
        
        // 科学计数法
        double scientific = 1.23e-4;   // 0.000123
        
        // 字符字面量
        char char_lit = 'A';
        char unicode_lit = '\u0041';   // Unicode A
        char escape_lit = '\n';        // 换行符
        
        // 字符串字面量
        string regular = "Hello, World!";
        string verbatim = @"C:\Users\Name\Documents";  // 逐字字符串
        string interpolated = $"Value: {decimal_lit}";   // 字符串插值
        
        // C# 11.0 原始字符串字面量
        string raw = """
            This is a raw string literal.
            It can contain "quotes" without escaping.
            And it preserves formatting.
            """;
        
        // 布尔字面量
        bool true_lit = true;
        bool false_lit = false;
        
        // null 字面量
        string null_lit = null;
        
        // 默认字面量 (C# 7.1+)
        int default_int = default;     // 等同于 default(int)
        string default_string = default; // 等同于 null
        
        Console.WriteLine("字面量演示完成");
        
        // 数字分隔符 (C# 7.0+)
        DemonstrateDigitSeparators();
    }
    
    private static void DemonstrateDigitSeparators()
    {
        Console.WriteLine("\n数字分隔符演示:");
        
        // 使用下划线作为数字分隔符
        int million = 1_000_000;
        long billion = 1_000_000_000L;
        double pi = 3.141_592_653_589_793;
        
        // 十六进制
        int hex = 0xFF_EC_DE_5E;
        
        // 二进制
        int binary = 0b1010_0001_1000_0101;
        
        Console.WriteLine($"百万: {million:N0}");
        Console.WriteLine($"十亿: {billion:N0}");
        Console.WriteLine($"π: {pi}");
        Console.WriteLine($"十六进制: 0x{hex:X}");
        Console.WriteLine($"二进制: {Convert.ToString(binary, 2)}");
    }
}

4. 类型转换

4.1 隐式和显式转换

using System;

public class TypeConversion
{
    public static void Main()
    {
        // 隐式转换(安全转换)
        int intValue = 42;
        long longValue = intValue;      // int -> long
        float floatValue = intValue;    // int -> float
        double doubleValue = floatValue; // float -> double
        
        Console.WriteLine($"隐式转换: {intValue} -> {longValue} -> {floatValue} -> {doubleValue}");
        
        // 显式转换(可能丢失数据)
        double largeDouble = 123.456;
        int truncatedInt = (int)largeDouble;  // 截断小数部分
        
        Console.WriteLine($"显式转换: {largeDouble} -> {truncatedInt}");
        
        // 溢出检查
        DemonstrateOverflowChecking();
        
        // 安全转换方法
        DemonstrateSafeConversion();
        
        // 字符串转换
        DemonstrateStringConversion();
        
        // 自定义类型转换
        DemonstrateCustomConversion();
    }
    
    private static void DemonstrateOverflowChecking()
    {
        Console.WriteLine("\n溢出检查演示:");
        
        try
        {
            // 默认情况下不检查溢出
            int maxInt = int.MaxValue;
            int overflow = maxInt + 1;  // 溢出,但不抛异常
            Console.WriteLine($"溢出结果: {maxInt} + 1 = {overflow}");
            
            // 使用 checked 检查溢出
            checked
            {
                int checkedOverflow = maxInt + 1;  // 抛出 OverflowException
            }
        }
        catch (OverflowException ex)
        {
            Console.WriteLine($"捕获溢出异常: {ex.Message}");
        }
        
        // 使用 unchecked 明确不检查溢出
        unchecked
        {
            int uncheckedOverflow = int.MaxValue + 1;
            Console.WriteLine($"unchecked 溢出: {uncheckedOverflow}");
        }
    }
    
    private static void DemonstrateSafeConversion()
    {
        Console.WriteLine("\n安全转换演示:");
        
        string numberString = "123";
        string invalidString = "abc";
        
        // TryParse 方法 - 安全转换
        if (int.TryParse(numberString, out int result))
        {
            Console.WriteLine($"转换成功: '{numberString}' -> {result}");
        }
        
        if (!int.TryParse(invalidString, out int invalidResult))
        {
            Console.WriteLine($"转换失败: '{invalidString}' 不是有效数字");
        }
        
        // Convert 类方法
        try
        {
            int converted = Convert.ToInt32("456");
            Console.WriteLine($"Convert.ToInt32: {converted}");
            
            bool boolValue = Convert.ToBoolean(1);
            Console.WriteLine($"Convert.ToBoolean(1): {boolValue}");
        }
        catch (FormatException ex)
        {
            Console.WriteLine($"格式异常: {ex.Message}");
        }
        
        // as 操作符(引用类型)
        object obj = "Hello";
        string str = obj as string;  // 如果转换失败返回 null
        if (str != null)
        {
            Console.WriteLine($"as 转换成功: {str}");
        }
        
        // is 操作符和模式匹配
        if (obj is string s)
        {
            Console.WriteLine($"is 模式匹配: {s}");
        }
    }
    
    private static void DemonstrateStringConversion()
    {
        Console.WriteLine("\n字符串转换演示:");
        
        // 数字转字符串
        int number = 42;
        string str1 = number.ToString();
        string str2 = number.ToString("D5");      // 5位数字,前导零
        string str3 = number.ToString("X");       // 十六进制
        
        Console.WriteLine($"ToString(): {str1}");
        Console.WriteLine($"ToString(\"D5\"): {str2}");
        Console.WriteLine($"ToString(\"X\"): {str3}");
        
        // 格式化字符串
        double price = 123.456;
        string currency = price.ToString("C");     // 货币格式
        string percent = (0.1234).ToString("P");   // 百分比格式
        string scientific = price.ToString("E");   // 科学计数法
        
        Console.WriteLine($"货币格式: {currency}");
        Console.WriteLine($"百分比格式: {percent}");
        Console.WriteLine($"科学计数法: {scientific}");
        
        // 字符串插值格式化
        Console.WriteLine($"插值格式化: {price:C}, {0.1234:P}, {price:E}");
    }
    
    private static void DemonstrateCustomConversion()
    {
        Console.WriteLine("\n自定义类型转换演示:");
        
        Temperature celsius = new Temperature(25);
        
        // 隐式转换
        double value = celsius;  // Temperature -> double
        Console.WriteLine($"隐式转换: {value}°C");
        
        // 显式转换
        Temperature fahrenheit = (Temperature)77;  // double -> Temperature
        Console.WriteLine($"显式转换: {fahrenheit.Value}°F");
    }
}

// 自定义类型转换示例
public class Temperature
{
    public double Value { get; }
    
    public Temperature(double value)
    {
        Value = value;
    }
    
    // 隐式转换操作符
    public static implicit operator double(Temperature temp)
    {
        return temp.Value;
    }
    
    // 显式转换操作符
    public static explicit operator Temperature(double value)
    {
        return new Temperature(value);
    }
}

5. 实践练习

练习1:数据类型综合应用

using System;
using System.Text;

public class DataTypeExercise
{
    public static void Main()
    {
        Console.WriteLine("=== 数据类型综合练习 ===");
        
        // 练习1:计算器
        Calculator calc = new Calculator();
        calc.RunCalculator();
        
        // 练习2:字符串处理
        StringProcessor processor = new StringProcessor();
        processor.ProcessText();
        
        // 练习3:数组操作
        ArrayOperations arrayOps = new ArrayOperations();
        arrayOps.ProcessArrays();
    }
}

public class Calculator
{
    public void RunCalculator()
    {
        Console.WriteLine("\n--- 简单计算器 ---");
        
        Console.Write("请输入第一个数字: ");
        if (double.TryParse(Console.ReadLine(), out double num1))
        {
            Console.Write("请输入运算符 (+, -, *, /): ");
            string op = Console.ReadLine();
            
            Console.Write("请输入第二个数字: ");
            if (double.TryParse(Console.ReadLine(), out double num2))
            {
                double result = op switch
                {
                    "+" => num1 + num2,
                    "-" => num1 - num2,
                    "*" => num1 * num2,
                    "/" => num2 != 0 ? num1 / num2 : double.NaN,
                    _ => double.NaN
                };
                
                if (double.IsNaN(result))
                {
                    Console.WriteLine("无效的运算或除零错误");
                }
                else
                {
                    Console.WriteLine($"结果: {num1} {op} {num2} = {result}");
                }
            }
        }
    }
}

public class StringProcessor
{
    public void ProcessText()
    {
        Console.WriteLine("\n--- 字符串处理器 ---");
        
        Console.Write("请输入一段文本: ");
        string input = Console.ReadLine() ?? "";
        
        if (string.IsNullOrWhiteSpace(input))
        {
            Console.WriteLine("输入为空");
            return;
        }
        
        // 统计信息
        int charCount = input.Length;
        int wordCount = input.Split(new char[] { ' ', '\t', '\n' }, 
                                   StringSplitOptions.RemoveEmptyEntries).Length;
        int digitCount = 0;
        int letterCount = 0;
        
        foreach (char c in input)
        {
            if (char.IsDigit(c)) digitCount++;
            if (char.IsLetter(c)) letterCount++;
        }
        
        Console.WriteLine($"字符总数: {charCount}");
        Console.WriteLine($"单词数: {wordCount}");
        Console.WriteLine($"数字字符数: {digitCount}");
        Console.WriteLine($"字母字符数: {letterCount}");
        Console.WriteLine($"大写: {input.ToUpper()}");
        Console.WriteLine($"小写: {input.ToLower()}");
        Console.WriteLine($"反转: {ReverseString(input)}");
    }
    
    private string ReverseString(string input)
    {
        char[] chars = input.ToCharArray();
        Array.Reverse(chars);
        return new string(chars);
    }
}

public class ArrayOperations
{
    public void ProcessArrays()
    {
        Console.WriteLine("\n--- 数组操作 ---");
        
        // 创建随机数组
        Random random = new Random();
        int[] numbers = new int[10];
        
        for (int i = 0; i < numbers.Length; i++)
        {
            numbers[i] = random.Next(1, 101);
        }
        
        Console.WriteLine($"原始数组: [{string.Join(", ", numbers)}]");
        
        // 统计
        int sum = 0;
        int max = numbers[0];
        int min = numbers[0];
        
        foreach (int num in numbers)
        {
            sum += num;
            if (num > max) max = num;
            if (num < min) min = num;
        }
        
        double average = (double)sum / numbers.Length;
        
        Console.WriteLine($"总和: {sum}");
        Console.WriteLine($"平均值: {average:F2}");
        Console.WriteLine($"最大值: {max}");
        Console.WriteLine($"最小值: {min}");
        
        // 排序
        int[] sortedNumbers = (int[])numbers.Clone();
        Array.Sort(sortedNumbers);
        Console.WriteLine($"排序后: [{string.Join(", ", sortedNumbers)}]");
        
        // 查找偶数
        var evenNumbers = new System.Collections.Generic.List<int>();
        foreach (int num in numbers)
        {
            if (num % 2 == 0)
            {
                evenNumbers.Add(num);
            }
        }
        
        Console.WriteLine($"偶数: [{string.Join(", ", evenNumbers)}]");
    }
}

6. 总结

本章详细介绍了 C# 的基本语法和数据类型:

主要内容

  1. 程序结构:命名空间、类、方法的组织方式
  2. 值类型:整数、浮点数、字符、布尔类型
  3. 引用类型:字符串、数组、对象
  4. 可空类型:处理 null 值的安全方式
  5. 类型推断:var 关键字的使用
  6. 常量和字面量:编译时和运行时常量
  7. 类型转换:隐式、显式、安全转换方法

关键要点

  • C# 是强类型语言,类型安全是核心特性
  • 值类型存储在栈上,引用类型存储在堆上
  • 可空类型提供了处理 null 值的安全机制
  • var 关键字提供类型推断,但不是动态类型
  • 类型转换要注意数据丢失和溢出问题

在下一章中,我们将学习 C# 的控制结构与流程控制。

参考资源