c#传递引用对象作为参数的时候就没有必要用ref关键字,对吗

兄弟哪位知道,c#传递引用对象作为参数的时候就没有必要用ref关键字,对吗?

我是这样理解的,我们在传递string,int这样的值类型的时候,如果必要则需要添加ref,但是对于引用对象来说,加不加ref都始终是传的这个地址,所以对于引用对象来说就不需要添加ref修饰词了。不知道对不对,请指点。
最新回答
一朵野菊

2025-06-18 01:35:00

传递引用对象时添加ref关键字和不添加还是有不同的。
不添加ref关键字时,作为方法参数的形参与实际传入的实参实际上是两个对象,在栈中有两个地方分别保存它们的名字,假设形参叫A,实参叫B。只是引用对象保存的本来就是地址,所以这两个对象的值“恰好”指向堆中的同一个地方,假设这个地方叫C,对这两个对象的值进行修改实际上是修改C,所以都会影响到另一个对象;假如我们对A重新赋值,相当于让A指向了堆中另一个地方D,这个操作当然不会对B有任何影响。此时我们修改AB的值相当于修改CD,相互之间也就没有什么关联了。
添加ref关键字时,方法将实参在栈中的位置当做实参的位置,此时形参就是实参,只是叫法不同。此时对形参的任何操作都会反映到实参上,因为两者本来就是同一个对象。可以参考下面的例子:

class Program
{
static void Main(string[] args)
{
Test a = new Test();
a.Value = 1;
Test b = a;
Change(b);//a.value值为1,b.value值为1;形参重新赋值没有影响到实参,方法结束后形参的
生命周期
也随之结束
b.Value = 2;//a.value值为2,b.value值为2;a和b指向同一地址
Change(ref b);//a.value值为2,b.value值为0;此时形参就是实参,只是叫法不一样
b.Value = 3;//a.value值为2,b.value值为3;两者已经指向不同地址了,相互之间不会影响
ReadKey();
}
static void Change(Test test)
{
test = new Test();
}
static void Change(ref Test test)
{
test = new Test();
}
}
class Test
{
public int Value;
}
幼稚园里的幼稚鬼

2025-06-18 06:09:07

如果你是要修改引用对象的属性可以不加ref,如果你是想改变这个引用本身,就必须加了。如:
public
class
Test
{
public
int
t;
public
Test(int
t)
{
this.t
=
t;
}
static
void
Main(string[]
args)
{
Test
t
=
new
Test(2);
ChangeProperty(t);
Console.WriteLine(t.t);
ChangeSelf(t);
Console.WriteLine(t.t);
ChangeSelf2(ref
t);
Console.WriteLine(t.t);
}
static
void
ChangeProperty(Test
t)
{
t.t
=
10;
}
static
void
ChangeSelf(Test
t)
{
t
=
new
Test(20);
}
static
void
ChangeSelf2(ref
Test
t)
{
t
=
new
Test(20);
}
}
伤疤像㈠朵鲜花

2025-06-18 01:27:00

加了ref 当方法试图改变参数名所对应的引用地址时,不会触发引用拷贝。如果不加ref那么修改参数名所对应的引用地址,那么就会触发引用拷贝。多线程模式下不建议加ref。
你可以这么理解:
“=”赋值运算符,在方法中,对于值类型(结构体)默认是拷贝值的形式,而对于对象(object)是拷贝引用的形式(这里的对象是指直接继承object的子类)。
加ref 会检测赋值运算符“=”所对应的原始引用并尝试修改。如果不加ref则遇到“=”时则拷贝引用(其实就是声明新的引用并赋值)。
所以:
你问的加不加ref,关键在于是否使用“=”来修改方法参数所对应的地址,如果方法中没有使用“=”来修改方法参数的地址则不用纠结是否加ref,如果你加了ref,编译器看到你在方法中有用“=”来修改地址,那么编译成IL之后也会忽略掉。