c# 引用类型和值类型


在C#中,类型主要被分为两大类:引用类型和值类型。这两者的主要区别在于它们在内存中的存储方式以及赋值、参数传递和函数返回时的行为。

### 值类型(Value Types)

值类型变量直接包含其数据。当你将一个值类型变量赋值给另一个变量时,实际上是将值复制到了新的变量中。因此,对新的变量所做的任何修改都不会影响到原始的变量。

C#中的值类型包括:

- 结构体(Struct)

- 枚举(Enum)

- 整型(int, long, short, byte, etc.)

- 浮点型(float, double, decimal)

- 布尔型(bool)

- 字符型(char)

### 引用类型(Reference Types)

引用类型变量存储的是对数据的引用(即内存地址),而不是数据本身。当你将一个引用类型变量赋值给另一个变量时,实际上是复制了引用,因此两个变量都指向同一块内存中的数据。这意味着,对通过其中一个变量所做的修改将反映到另一个变量上。

C#中的引用类型包括:

- 类(Class)

- 接口(Interface)

- 委托(Delegate)

- 数组(Array)

- 字符串(String,虽然在.NET中字符串是不可变的,但它在内部是作为引用类型处理的)

### 示例代码

这里提供一个简单的示例来说明值类型和引用类型的区别:


using System;

class Program
{
    struct Point // 值类型:结构体
    {
        public int X, Y;
    }

    class Rectangle // 引用类型:类
    {
        public Point TopLeft;

        public Rectangle(int x, int y)
        {
            TopLeft = new Point { X = x, Y = y };
        }
    }

    static void Main()
    {
        Point p1 = new Point { X = 1, Y = 2 }; // 值类型实例
        Point p2 = p1; // 复制值
        p2.X = 10; // 修改p2的X值,p1不受影响

        Console.WriteLine($"p1.X: {p1.X}, p2.X: {p2.X}"); // 输出:p1.X: 1, p2.X: 10

        Rectangle r1 = new Rectangle(1, 2); // 引用类型实例
        Rectangle r2 = r1; // 复制引用
        r2.TopLeft.X = 10; // 修改r2引用的对象的TopLeft的X值

        Console.WriteLine($"r1.TopLeft.X: {r1.TopLeft.X}, r2.TopLeft.X: {r2.TopLeft.X}"); // 输出:r1.TopLeft.X: 10, r2.TopLeft.X: 10

        // 注意:如果Rectangle类中的TopLeft是一个私有字段,并且有一个设置TopLeft的公共方法,
        // 那么你需要通过那个方法来修改TopLeft,而上述直接访问的方式将不再适用。
    }
}

这个示例展示了值类型和引用类型在赋值和修改数据时的不同行为。