jus*_*rld 3 c# pass-by-reference pass-by-value
在C#中,据我所知,方法调用期间参数的传递是按值进行的.但是当您使用对象作为参数时,您传递的是对象本身的引用.这意味着如果您访问(并修改)对象内部字段的值,则一旦方法调用完成,也将看到更新.
因此,如果我在方法中修改String的值,则应在方法调用终止时修改它(因为String是C#中的对象).但事实并非如此,事实上如果我写:
public static void main (String []args){
String s= "hello";
method(s);
System.Console.Writeline(s);
}
public void method (String s)
{s = "world";}
Run Code Online (Sandbox Code Playgroud)
它将打印"你好",而不是"世界".打印"世界"的唯一方法是ref在方法签名和调用中添加关键字.
为什么会这样?我的答案(我希望你确认或纠正)是在C#中String对象是不可变的,所以如果我使s ="world"实际上编译器正在创建一个新的字符串对象,但是对象的引用是不会改变(因为通过是值).
事实上,如果我s.getHashCode()在method()通话前后打印,这两个值是不同的.
你怎么看待我的解释?
因此,如果我在方法中修改String的值,则应在方法调用终止时修改它(因为String是C#中的对象).但事实并非如此,事实上如果我写:
你没有修改String对象.您正在修改参数以引用其他参数String.这只是改变一个局部变量,而不是由调用者看到.
正如值一样,String引用按值传递.您需要区分更改参数的值和修改参数值引用的对象.您将看到与您自己的类完全相同的行为,即使它是可变的:
class Person
{
public string Name { get; set; }
}
class Test
{
static void Main()
{
var p = new Person { Name = "Tom" };
Method(p);
Console.WriteLine(p.Name);
}
static void Method(Person parameter)
{
parameter = new Person { Name = "Robin" };
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果Method您在对象中进行了更改,例如
static void Method(Person parameter)
{
parameter.Name = "Robin";
}
Run Code Online (Sandbox Code Playgroud)
... 然后你会看到输出的变化.但那不是修改参数.字符串不变性相关的唯一原因是它意味着Method当参数是字符串时,上面的第二个版本没有等效(在安全代码中).
有关详细信息,请参阅有关参数传递的文章.
| 归档时间: |
|
| 查看次数: |
3403 次 |
| 最近记录: |