我理解,如果我传递一个值类型( int
, struct
等)作为参数(没有 ref
关键字),该变量的副本将传递给该方法,但如果我使用 ref
关键字对该方法的引用传递变量,而不是新变量 .
但是使用引用类型(如类),即使没有 ref
关键字,也会将引用传递给方法,而不是副本 . 那么 ref
关键字与引用类型的用途是什么?
举个例子:
var x = new Foo();
以下有什么区别?
void Bar(Foo y) {
y.Name = "2";
}
和
void Bar(ref Foo y) {
y.Name = "2";
}
10 回答
它允许您修改传入的引用 . 例如
如果您不关心传入的引用,也可以使用 out :
在某些情况下,您要修改实际的 reference 而不是指向的对象:
Jon Skeet写了关于C#参数传递的a great article . 它详细说明了按值,引用(
ref
)和输出(out
)传递参数的确切行为和用法 .以下是该页面与
ref
参数相关的重要引用:这里非常好解释:http://msdn.microsoft.com/en-us/library/s6938f28.aspx
摘自文章:
您可以使用
y
更改foo
指向的内容:使用ref关键字传递引用类型时,通过引用传递引用,并且调用的方法可以为参数指定新值 . 该更改将传播到调用范围 . 如果没有ref,引用将按值传递,这不会发生 .
C#也有'out'关键字,它与ref非常相似,除了使用'ref'之外,必须在调用方法之前初始化参数,并且使用'out'必须在接收方法中指定一个值 .
除了现有的答案:
当您询问两种方法的区别时:使用
ref
或out
时没有co(ntra)方差:方法中的参数似乎总是传递副本,问题是什么的副本 . 副本由对象的复制构造函数完成,因为所有变量都是C#中的Object,我相信所有这些都是这种情况 . 变量(对象)就像生活在某些地址的人一样 . 我们要么改变居住在这些地址的人们,要么我们可以为电话簿中那些地址的人们创建更多的参考资料(制作浅层副本) . 因此,多个标识符可以引用相同的地址 . 引用类型需要更多空间,因此与通过箭头直接连接到堆栈中的标识符的值类型不同,它们具有堆中另一个地址的值(更大的空间) . 这个空间需要从堆中获取 .
值类型:标识符(包含值=堆栈值的地址)---->值类型的值
引用类型:标识符(包含值=堆栈值的地址)---->(包含值=堆值的地址)---->堆值(通常包含其他值的地址),想象更多箭头粘在不同的数组[0],数组[1],数组[2]的方向
更改值的唯一方法是遵循箭头 . 如果一个箭头丢失/更改的方式无法访问该值 .
参考变量将地址从一个地方带到另一个地方,因此任何地方对它们的任何更新都将反映在所有地方,那么REF的用途是什么 . 引用变量是好的,直到没有新的内存分配给方法中传递的引用变量 . 一旦新内存分配,那么对此的值更改将不会反映在任何地方 . 对于这个参考来 . Ref是引用的引用,因此每当新内存分配它就会知道因为它指向该位置,因此值可以由everyOne共享 . 您可以看到图像更清晰 .
另一堆代码