如何在C#中通过ref传递
本文关键字:ref 传递 | 更新日期: 2023-09-27 18:00:48
在我的一个类(ClassA)中,我想创建另一个类的相关实例(ClassB),为它提供对发起创建它的对象的引用。因此,我为ClassB提供了一个采用(ref ClassB parent)参数的构造器。但在ClassA中,我不能只调用var child=new ClassB(引用this)。如何实现?
ref
关键字会导致传递引用语义-也就是说,如果变量在被调用函数中被重新分配,它也会在调用方中重新分配。
显然,只有当变量2(可以重新赋值)作为参数直接传递时,这才有效,如果传递任意表达式,这将不起作用。在这种情况下,this
不是一个变量,而是一个不能重新赋值的特殊表达式,因此不能使用。
因此,这将起作用:(但请查看其他答案,并继续阅读为什么这可能是不需要的和/或只是愚蠢的。)
var me = this;
var other = new ClassB(ref me);
但是,不应将"按ref
传递"与"按对象传递[Sharing]1"语义混淆。传递对象意味着如果传递了对象,则传递对象:对象不是复制/克隆/复制的如果对象发生突变,则该对象非使用ref
或out
,否则所有引用类型在C#中都具有传递对象语义。(class
关键字声明了一个新的引用类型,就像文章中的情况一样)。
另一方面,值类型(例如struct
),包括int
、Guid
和KeyValuePair<K,V>
,具有传递值语义-在这种情况下,会生成一个副本,因此,如果修改了值,则只有值结构(它是一个副本)会更改。
快乐编码
1Underneath C#/.NET通过按值传递对对象的引用来实现按对象传递。然而,上面的规则正确地描述了可观察的语义和效果。
2与C#不同,C#只允许变量与ref
一起使用,VB.NET允许使用Properties。VB.NET编译器在编译期间自动创建临时变量和属性的隐式读/写指令。
ref
指的是变量引用,而不是对象引用。
如果只想传递对对象的引用,则不需要ref
关键字。对象已经是引用类型,所以它们的引用是通过值传递的。对象本身不会被复制。
因此,在构造函数和实例化中都不需要ref
关键字:
public ClassB(ClassA parent)
{
}
var child = new ClassB(this);
在这种情况下,您不需要通过ref。如果您正在传递ClassB(this),那么它将通过引用传递,而不是通过值传递。对传递到类B的构造函数中的类A实例所做的任何更改也将应用于类A。
您真的需要ref关键字吗?所有类型基本上都是通过引用传递的,所以如果你有ClassB以ClassA作为构造函数参数,只需传递新的ClassB(this),就不需要使用引用。
不能更改this
指针,这是ref
关键字允许的。你为什么不能这样申报B类?
ClassA m_classA;
public ClassB(ClassA classA)
{
m_classA = classA;
}