C# - 传递引用与值
介绍
在本指南中,我们将研究在 C# 方法中将引用类型和值类型作为参数传递的区别。如果不理解这一点,很容易更改错误的变量,并花费数小时试图弄清楚发生了什么。
引用类型
引用类型变量包含对存储在内存(也称为堆)中的数据的引用。堆最常用于存储寿命较长的数据。您可以让多个变量指向相同的引用数据。对象就是引用类型的一个例子。
var a = new Student();
var b = a;
在上面的例子中,变量a和b都指向内存中的同一个 student 对象。如果我们改变a,我们也将改变b。这是因为a和b不是存储数据,而是存储数据位置的引用。
值类型
值类型变量是不可变数据,它包含数据,而不是对数据的引用。值类型的生命周期通常很短。它们通常存储在内存中称为堆栈的区域中。堆栈是不需要长期存在的数据所在位置。结构、Int32、DateTime 和 Double 都是值类型的示例。
传递引用类型
默认情况下,将引用类型变量传递给方法会传递引用的副本,而不是实际数据。如果您更改引用类型内部的值,这也会更改方法外部的值,因为它指向内存中的相同引用位置。当您尝试将变量分配给方法内的新对象时,会出现一个警告。这将使变量不再指向内存中的引用对象。此后的任何更改都不会反映在原始引用对象中。以下是一个例子:
class ReferenceTypeExample
{
static void Enroll(Student student)
{
student.Enrolled = true; // This changes the student variable that was passed in outside of the method.
student = new Student(); // This does not change the student variable outside of the method but creates a new reference. Since student now points to a new reference, the student variable outside of the method is no longer affected after this line.
student.Enrolled = false; // This changes the local student inside the method.
}
static void Main()
{
var student = new Student
{
Name = "Susan",
Enrolled = false
};
Enroll(student);
// student.Name is still Susan
// student.Enrolled is now true
}
}
public class Student {
public string Name {get;set;}
public bool Enrolled {get;set;}
}
传递值类型
当将值类型传递到方法中时,该值被视为方法的本地值。在方法内部执行的任何操作都不会改变原始变量。
class ReferenceTypeExample
{
static void Enroll(bool enrollmentStatus)
{
// This will not change any value outside the method.
enrollmentStatus = true;
}
static void Main()
{
var student = new Student
{
Name = "Susan",
Enrolled = false
};
Enroll(student.Enrolled);
// student.Enrolled still equals false.
}
}
public class Student {
public string Name {get;set;}
public bool Enrolled {get;set;}
}
概括
了解这些简单的技巧可以防止您犯改变数据价值的错误。
要了解有关在 C# 中传递引用类型、值类型和其他类型的更多信息,请查看Scott Allen 撰写的《加速 C# 基础知识》。别忘了尝试C# 路径,看看你的技能处于什么水平以及在哪些方面可以提高!
关于作者
Matt Ferderer 是一名软件开发人员,他在推特、帖子和博客上发布有关网络开发的信息。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~