我已经阅读了passng和不在参数中传递ref之间的区别,但是,我何时想要使用它们?
例如,我在一个方法中有一些逻辑可以重构为它自己的方法.Resharper 4.5将参数之一作为ref类型,但如果我手动进行重构,我认为我不会这样做.
显然我缺少一些理解.也许当编码中的某些类型或某些场景错过ref关键字时会发生什么情况会有所帮助?
谢谢
让我把它分解为两个问题:
1)何时应该在编写方法时使用ref/out形式参数声明?
当您希望您的方法能够读取和写入从调用者传入的变量时,请使用ref/out ,而不是仅仅读取值.
2)为什么"提取方法"重构会产生ref参数?
我不知道Resharper的细节,但我可以猜一猜.考虑以下邪恶的可变值类型:
struct S
{
private int x;
public int X() { return this.x; }
public void M() { this.x += 1; }
}
Run Code Online (Sandbox Code Playgroud)
你有一个方法:
void Foo()
{
S s = new S();
Fred(s);
Blah(s);
Bar(s);
s.M();
Console.WriteLine(s.X()); // prints 1
}
Run Code Online (Sandbox Code Playgroud)
你在中间位上做"提取方法":
void NewMethod(ref S s)
{
Blah(s);
Bar(s);
s.M();
}
void Foo()
{
S s = new S();
Fred(s);
NewMethod(ref s);
Console.WriteLine(s.X()); // still prints 1
}
Run Code Online (Sandbox Code Playgroud)
相反,如果您创建了一个没有"ref"的方法,那么调用NewMethod会将s的副本传递给NewMethod.请记住,值类型按值复制; 这就是为什么我们称它们为"价值类型".它将是变异的副本,然后sX()返回零.重构在程序中引入语义变化是一个坏主意,重构引擎很难知道给定方法是否依赖于值类型的可变性.
这只是你应该避免使用可变值类型的另一个原因.
| 归档时间: |
|
| 查看次数: |
517 次 |
| 最近记录: |