最新消息:把Logo换了一下,虽然丑了点,但至少完全是自己的设计

C#中值类型和引用类型区别

CSharp 宇托 240浏览 暂无评论

在C#中,所有的东西都是对象。但在对象类型中,又分为值类型和引用类型。

两者的主要区别是:

  • 值类型的内存空间分配在栈上;而引用类型的内存空间分配在堆上。
  • 栈的内存分配是自动释放;而堆的内存是由GC(垃圾回收)来释放
  • 值类型存取速度快,引用类型存取速度慢。
  • 类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针或引用
  • 值类型继承自System.ValueType(ValueType是继承自System.Object的),引用类型继承自System.Object
  • 引用类型的Equals方法默认比较地址,而值类型的默认比较值。
  • 引用类型可以派生出新的类型,而值类型不能;
  • 引用类型可以设置为null值,值类型一般不能(只有Nullable<T>可以设置为null值)
  • 引用类型变量的赋值只复制对对象的引用,而不复制对象本身。而将一个值类型变量赋给另一个值类型变量时,将复制对象。
  • 值类型一旦定义,则不可以变

值类型

C#中,所有类型都是从Object扩展出来的,值类型是扩展自Object的子类ValueTypeValueType不允许继承,在C#中,只有两个东西是从ValueType中继承来的。一个是结构体:struct,一个是枚举:enum所以说值类型只能是结构体struct或者枚举enum,也可以说结构体struct和枚举enum都是值类型

枚举enum相对来说更加特殊,它可以继承自byte, sbyte, short, ushort, int, uint, long, ulong,可以把它看成一个特殊的数字类型,当然也可以把它看成是一个结构体struct

因为无法直接继承ValueType,我们要定义值类型,只能定义成结构体struct或者枚举enum

在其它语言中所谓的基本类型,在C#中,都是结构体struct。要注意的是,DateTime也是结构体struct

C#3.0追加的Nullable<T>也是结构体struct

上面的这些都可以通过看API来了解。

比如DateTime的API地址:https://msdn.microsoft.com/en-us/library/system.datetime(v=vs.110).aspx

引用类型

除值类型以外的都是引用类型,C#大体有以下一些引用类型

  • 数组
  • 接口
  • 委托
  • 字符串(不可变对象)

测试代码

以下代码大体可以说明一些值类型和引用类型的区别。

C#
class Program
{
    struct ValPerson
    {
        public string Name;
        public int Age;

        public ValPerson(string name, int age)
        {
            this.Name = name;
            this.Age = age;
        }

        public override string ToString()
        {
            return string.Format("{0}: {1}", Name, Age);
        }
    }

    class ObjPerson
    {
        public string Name;
        public int Age;

        public ObjPerson(string name, int age)
        {
            this.Name = name;
            this.Age = age;
        }

        public override string ToString()
        {
            return string.Format("{0}: {1}", Name, Age);
        }
    }

    static void Main(string[] args)
    {
        ValPerson valPersonA = new ValPerson("ValPerson", 20);
        ObjPerson objPersonA = new ObjPerson("ObjPerson", 30);

        Console.WriteLine("valPersonA->" + valPersonA);
        Console.WriteLine("objPersonA->" + objPersonA);

        var valPersonB = valPersonA;
        var objPersonB = objPersonA;

        valPersonB.Age = 21;
        objPersonB.Age = 31;

        Console.WriteLine("valPersonA->" + valPersonA);
        Console.WriteLine("objPersonA->" + objPersonA);
        Console.WriteLine("valPersonB->" + valPersonB);
        Console.WriteLine("objPersonB->" + objPersonB);

        Console.ReadKey();
    }
}

结果如下:

valPersonA->ValPerson: 20
objPersonA->ObjPerson: 30
valPersonA->ValPerson: 20
objPersonA->ObjPerson: 31
valPersonB->ValPerson: 21
objPersonB->ObjPerson: 31

转载请注明:宇托的狗窝 » C#中值类型和引用类型区别

发表我的评论
取消评论

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址