我已经在Troelsen和Schildt的书中读过这篇文章。现在我很困惑。他们在这个问题上的看法是不同的.Schildt解释说,在你通过ref传递例如整数类型的情况下,函数得到了地址的副本这显示了变量在堆中的位置.Troelsen解释了该函数获取oriignal副本....如果可能的话,我很想听到当refrenece类型通过ref时的情况...
答案 0 :(得分:3)
当您使用ref
将变量作为参数传递给方法时,您不仅仅是传递参数 - 您将对该变量本身进行该方法控制。 (这就是为什么你只能使用ref
而不是属性来传递变量。)
如果我有变量
var x = 1;
我将其传递给方法,不用 ref
void DoSomethingWith(int arg)
{
arg++;
}
DoSomethingWith(x);
然后该方法,DoSomethingWith
可以使用arg
执行任何操作。但对于调用方法,x
仍然等于1。
但是如果我使用ref
void DoSomethingWith(ref int arg)
{
arg++;
}
DoSomethingWith(ref x);
然后我给那个方法控制我的变量x
。如果它向arg
添加1,那么它也会向x
添加1。
对于引用类型来说,这有点令人困惑,因为无论您是否使用ref
,方法都可以修改对象的状态。例如,如果您将List<object>
传递给方法,则无论您是否使用ref
,该方法都可以在列表中添加或删除项目。
但是,如果你使用ref
,那么该方法将获得对你的变量的控制权。它可以创建不同的List<object>
并将其分配给您的变量。它可以将您的变量设置为null
。如果您不使用ref
,则无法执行此操作。
如果我调用此方法 - 没有ref
- 并传递字符串列表
void DoSomethingWithList(List<string> list)
{
list.Add("Hello!");
list = new List<string>();
list.Add("Goodbye!");
}
这将添加“你好!”到我传入的列表。但是当它创建一个新的List<string>
时,它不会影响我传递给方法的变量。该变量仍将引用相同的列表,现在使用字符串“Hello!”添加到它。
但如果它使用ref
void DoSomethingWithList(ref List<string> list)
{
list.Add("Hello!");
list = new List<string>();
list.Add("Goodbye!");
}
然后我传入的任何变量都将替换为新列表。当方法完成后,我的变量将包含一个带有“Goodbye!”字样的新List<string>
。
这是一个blog post,其中包含更多示例。
ref
的{{3}}解释了这一点。但是,与许多文档一样,它更多的是准确而不是易于阅读和理解。一旦你理解了这一点就很有道理,但如果你还不知道它,我会发现它很难理解。
通过引用传递的效果是对参数的任何更改 在被调用的方法中反映在调用方法中。例如, 如果调用者传递局部变量表达式或数组元素 访问表达式,被调用的方法替换了对象 ref参数引用,然后是调用者的局部变量或者 数组元素现在引用新对象。
也许这只是我,但我认为如果有人在寻找像ref
之类的信息和像“数组元素这样的术语”,我认为这没有用
访问表达“被抛入。即使它不是火箭科学,它也会给试图掌握新概念的人增加一点负担。