在C#中,值范例和援用范例是相称主要的两个观点,必须在设想范例的时刻就决议范例实例的行动。假如在编写代码时不能明白援用范例和值范例的区分,那末将会给代码带来不必要的非常。许多人就是由于没有弄清楚这两个观点从而在编程过程当中遇到了许多题目,在这里博主浅谈对值范例和援用范例的熟悉。
首先从观点上看,值范例直接存储其值,而援用范例存储对其值的援用。从而这两种范例存储在内存的差别处所。
其次从内存空间上看,值范例是在栈中操纵,而援用范例则在堆中分派存储单元。
栈在编译的时刻就分派好内存空间,在代码中有栈的明白定义,而堆是顺序运转中动态分派的内存空间,能够依据顺序的运转状况动态地分派内存的大小。因而,值范例总是在内存中占用一个预定义的字节数。而援用范例的变量则在栈中分派一个内存空间,这个内存空间包括的是对另一个内存位置的援用,这个位置是托管堆中的一个地点,即寄存此变量现实值的处所。
也就是说值范例相称于现金,要用就直接用,而引范例相称于存折,要用得先去银行取。
但值范例在栈上分派内存,而援用范例在托管堆上分派内存,只是一种笼统的说法。下面临其举行细致描述。
(1)关于值范例的实例,假如作为要领中的局部变量,则被建立在线程栈上;假如该实例作为范例的成员,则作为范例成员的一部分,连同其他范例字段寄存在托管堆上。
每种值范例均有一个隐式的默许组织函数来初始化该范例的默许值。比方:
int i = new int();
等价于:
Int32 i = new Int32();
等价于:
int i = 0;
等价于:
Int32 i = 0;
运用new运算符时,将挪用特定范例的默许组织函数并对变量赋以默许值。在上例中,默许组织函数将值0赋给了i。
申明:C#的一切值范例均隐式派生自System.ValueType,而System.ValueType直接派生于System.Object。即System.ValueType自身是一个类范例,而不是值范例。其关键在于ValueType重写了Equals要领,从而对值范例根据实例的值来比较,而不是援用地点来比较。
(2)援用范例的实例建立在托管堆上。
下面以一段代码来细致解说一下值范例与援用范例的区分
namespace Test { class Program { static void Main(string[] args) { //挪用ReferenceAndValue类中的Demonstration要领 ReferenceAndValue.Demonstration(); Console.ReadLine(); } } public class stamp //定义一个类 { public string Name { get; set; } //定义援用范例 public int Age { get; set; } //定义值范例 } public static class ReferenceAndValue //定义一个静态类 { public static void Demonstration() //定义一个静态要领 { stamp Stamp_1 = new stamp { Name = "Premiere", Age = 25 }; //实例化 stamp Stamp_2 = new stamp { Name = "Again", Age = 47 }; //实例化 int age = Stamp_1.Age; //猎取值范例Age的值 Stamp_1.Age = 22; //修正值范例的值 stamp guru = Stamp_2; //猎取Stamp_2中的值 Stamp_2.Name = "Again Amend"; //修正援用的Name值 Console.WriteLine("Stamp_1's age:{0}", Stamp_1.Age); //显现Stamp_1中的Age值 Console.WriteLine("age's value:{0}", age); //显现age值 Console.WriteLine("Stamp_2's name:{0}", Stamp_2.Name); //显现Stamp_2中的Name值 Console.WriteLine("guru's name:{0}", guru.Name); //显现guru中的Name值 } } }
经由过程运转上面一段顺序以后我们能够看出,当转变了Stamp_1.Age的值时,age并没有随着变,但在转变了anders.Name的值后,guru.Name却随着变了,这就是值范例和援用范例的区分。在声明age值范例变量时,将 Stamp_1.Age的值赋给它,这时候,编译器在栈上分派了一块空间,然后把Stamp_1.Age的值填进去,两者没有任何关联,就像在计算机中复制文件一样,只是把Stamp_1.Age的值拷贝给age了。而援用范例则差别,在声明guru时把Stamp_2赋给它,前面说过,援用范例包括的只是堆上数据地区地点的援用,实在就是把Stamp_2的援用也赋给guru,因而它们指向了统一块内存地区。既然是指向统一块地区,不论修正谁,另一个的值都邑随着转变,就像信用卡跟亲情卡一样,用亲情卡取了钱,与之关联的信用卡账上也会随着发生变化。
以上就是C#中值范例与援用范例的细致引见的细致内容,更多请关注ki4网别的相干文章!