ref修饰符如何适用于值和引用类型?有人可以解释一下吗?

时间:2016-06-24 09:41:15

标签: c# .net

我已经在Troelsen和Schildt的书中读过这篇文章。现在我很困惑。他们在这个问题上的看法是不同的.Schildt解释说,在你通过ref传递例如整数类型的情况下,函数得到了地址的副本这显示了变量在堆中的位置.Troelsen解释了该函数获取oriignal副本....如果可能的话,我很想听到当refrenece类型通过ref时的情况...

1 个答案:

答案 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之类的信息和像“数组元素这样的术语”,我认为这没有用 访问表达“被抛入。即使它不是火箭科学,它也会给试图掌握新概念的人增加一点负担。