猿教程 Logo

C# 值类型和引用类型

我们已经在上一节中了解了C#的数据类型。 在C#中,这些数据类型基于如何将它们的值存储在存储器中进行分类。 C#包括以下类别的数据类型:

  1. 值类型

  2. 参考类型


值类型

如果数据类型在其自己的存储器空间内保存数据值,则该数据类型是值类型。 这意味着这些数据类型的变量直接包含它们的值。

例如,考虑整数变量

int i = 100;

系统在分配给变量'i'的存储器空间中存储100。 下图说明了如何将100存储在存储器中的某个假设位置(0x239110):“i”:


以下数据类型都是值类型:

  • bool

  • byte

  • char

  • decimal

  • double

  • enum

  • float

  • int

  • long

  • sbyte

  • short

  • struct

  • uint

  • ulong

  • ushort


值传递

当您将值类型变量从一个方法传递到另一个方法时,系统会在另一个方法中创建一个变量的单独副本,因此如果在一个方法中更改值不会影响另一个方法中的变量。

值传递案例;

static void ChangeValue(int x)
{
    x =  200;
    Console.WriteLine(x);
}
static void Main(string[] args)
{
    int i = 100;
    Console.WriteLine(i);
    
    ChangeValue(i);
    
    Console.WriteLine(i);
}

输出:

100
200
100

在上面的例子中,Main()方法中的变量i保持不变,即使我们将它传递给ChangeValue()方法并改变它的值。


引用类型

与值类型不同,引用类型不直接存储其值。 相反,它存储值正被存储的地址。 换句话说,引用类型包含指向保存数据的另一个存储器位置的指针。

例如,参考以下字符串变量:

string s =“Hello World !!”;

下图显示了系统如何为上述字符串变量分配内存。


如上图所示,系统为内存中的一个随机位置(0x803200)选择变量's'。 变量s的值为0x600000,它是实际数据值的存储器地址。 因此,引用类型存储存储实际值的位置的地址,而不是值本身。

以下数据类型是引用类型:

  • String

  • 所有数组,即使它们的元素是值类型

  • Class

  • Delegates


引用传递

当您将引用类型变量从一个方法传递到另一个方法时,它不会创建新副本; 相反,它传递变量的地址。 如果我们现在改变一个方法中的变量的值,它也将反映在调用方法中。

引用传递案例:

static void ChangeReferenceType(Student std2)
{
    std2.StudentName = "Steve";
}
static void Main(string[] args)
{
    Student std1 = new Student();
    std1.StudentName = "Bill";
    
    ChangeReferenceType(std1);
    Console.WriteLine(std1.StudentName);
}

Output:

Steve

在上面的例子中,由于Student是一个对象,当我们发送Student对象std1到ChangeReferenceType()方法时,实际发送的是std1的内存地址。 因此,当ChangeReferenceType()方法更改StudentName时,它实际上改变了std1的StudentName,因为std1和std2都指向内存中的相同地址。 因此,输出是Steve。


Null

引用类型在未初始化时默认具有空值。 例如,一个字符串变量(或引用类型数据类型的任何其他变量),没有为其分配值。 在这种情况下,它有一个空值null,这意味着它不指向任何其他内存位置,因为它还没有值。


值类型变量不能为空,因为它保存的值不是内存地址。 但是,值类型变量必须在使用前分配一些值。 如果尝试使用本地值类型变量而不为其分配值,编译器将出错。

编译时错误案例:

void someFunction()
{
    int i;
    Console.WriteLine(i);
}

但是,类中的值类型字段可以在没有初始化的情况下声明(字段不是函数中的局部变量)。 如果未分配任何值,它将具有默认值,例如,int将为0,布尔将为false等等。

值类型案例:

class myClass
{
    public int i;
}
myClass mcls = new myClass();
Console.WriteLine(mcls.i);

输出:

0

访问MSDN阅读有关值类型的默认值

记住要点
  • 值类型将值存储在其存储空间中,而引用类型存储存储值的地址。

  • 原始数据类型和结构体是“值”类型。 类对象,字符串,数组,委托是引用类型。

  • 默认情况下,值类型传递byval。 默认情况下,引用类型传递byref。

  • 存储在堆栈和堆中的值类型和引用类型取决于变量的范围。


版权声明:本站所有教程均为本站原创或翻译,转载请注明出处,请尊重他人劳动果实。请记住本站地址:www.yuanjiaocheng.net (猿教程) 作者:卿文刚
本文标题: C#环境
本文地址:http://www.yuanjiaocheng.net/CSharp/cshart-value-reference-type.html