为什么"ref"关键字与System.ServiceModel.Channels.Message一起使用?

daz*_*ler 3 c# ref pass-by-reference

我现在正在查看一些C#代码,我想检查一下,在我理解它应该如何工作的时候我不会疯狂.

它与传递System.ServiceModel.Channels.Message有关.采用Message对象的每个方法都有一个类似于此的方法签名:

void SomeMethod(ref Message message) { ... }
Run Code Online (Sandbox Code Playgroud)

我不明白为什么"ref"关键字在那里.据我所知,如果该方法不会完全替换该对象,则不需要它.

void SomeMethod(ref Message message)
{
    message = new Message();
}
Run Code Online (Sandbox Code Playgroud)

但是,如果消息,例如,只是在标题中添加了其他内容,或者只是从对象中读取值,则不需要"ref"关键字,因为Message是引用类型.

void SomeMethod(Message message)
{
    message.Headers.Add("Some Data");  // This should be fine?
}
Run Code Online (Sandbox Code Playgroud)

干杯

Eri*_*ert 8

首先,你可能是正确的; 编写代码的人很可能错误地添加了"ref".

我想借此机会确保您清楚地了解"参考"的含义.它意味着" 为这个变量做一个别名 ".也就是说,当你说:

M(ref string x) { x = null; }
N(string x) { x = null; }
...
string y = "abc";
N(y);
M(ref y);
Run Code Online (Sandbox Code Playgroud)

N(y)means 的调用会复制y中的引用,并将该引用放在x中.以呼叫M(ref y)方式的X和Y现在同一变量两个名字.也就是说,x成为一个别名y.

非常不幸的是我们选择"ref"作为关键字,因为它立即让人们对引用类型和值类型感到困惑.它与引用类型和值类型没有任何关系. "ref"表示" 我指的是另一个变量 ".

ref和之间的区别out仅仅是ref要求在调用之前初始化别名变量,而out不是.(两者都保证在调用正常完成初始化变量.)

  • @Alan:我明白你的意思了.但"ref"确实表达了*实现细节*.事实上,这是对包含对存储位置的引用的存储位置的引用,从编译器开发人员的角度来看很有意思,但它对用户没有多大意义,毕竟没有别的方法利用该实现细节. (2认同)