List <t>或集合的编码样式“ref”

时间:2015-11-30 16:24:51

标签: c# coding-style

我有更改List类型的参数的功能(更改内部对象状态)。例如:

    public void ChangeList<T>(List<T> source, T value)
    {
        //Actions
        source.Add(value);
        //Actions
    }

什么是功能签名更好?为什么?

首先:public void ChangeList<T>(List<T> source, T value)

第二:public void ChangeList<T>(ref List<T> source, T value)

修改:可以更改问题。如何明确指定函数更改列表的状态? (函数名称或ReadonlyCollection除外)

3 个答案:

答案 0 :(得分:8)

第一个。第二个人尖叫“我不知道ref的含义”;这里完全错了。这真的不是一个风格问题。在此上下文中使用ref的唯一原因是,重新分配列表所需的ChangeList方法(返回不同的列表实例,而不是按照名称所示,并且改变现有的清单)。在那种情况下,我认为return会更好:

public List<T> TransformBasedOnList<T>(List<T> source, T value) { ... }

答案 1 :(得分:0)

只有在更改List的引用时才应使用ref: 例如

public void ChangeList<T>(ref List<T> source, T value)
{
    //Actions
    source = new List<T>; // or initialize using API/DB call
    source.Add(value);
    //Actions
}

答案 2 :(得分:0)

扩展我的评论,请参阅此示例应用程序,该应用程序展示了通过ref传递参数之间的区别:

static void Main(string[] args)
{
    int val = 1;
    int val2 = 1;

    Add(ref val);
    Add(val2);
    Console.WriteLine("Add 44 to Refence of val: " + val);
    Console.WriteLine("Add 44 to i, not by ref:  " + val2);

    Console.ReadKey();
}

static void Add(ref int i)
{
    i += 44;
}

static void Add(int i)
{
    i += 44;
}

输出:

enter image description here

正如您所看到的,当您通过ref传递值时,您可以更改&#34;外部&#34;被调用方法的范围。调用方法知道这些更改。基本上,被调用的方法&#34;引用了该变量的存储位置&#34;并且该位置已分配值。我的控制台输出中有一个type-o,应该说Add 44 to val2, not by ref:

当您使用ref时,更改无法获得&#34;识别&#34;超出被调用方法的范围。相反,它传递了参数/参数的,忽略了实际的内存引用,只更改了方法的本地值。

不是一个很好的解释,说实话,我的词汇在这件事上并不引人注目(如果有人能纠正我,我会喜欢它!)但我觉得这个例子很简单,截图清楚地显示差异。

编辑:此外,只需重新链接MSDN:

https://msdn.microsoft.com/en-us/library/14akc2c7.aspx

并指出这个重要的注释,

  

不要将引用传递的概念与引用类型的概念混淆。这两个概念不尽相同。无论是值类型还是引用类型,都可以通过ref修改方法参数。通过引用传递时,没有值类型的装箱。

A&#34;参考类型&#34;基本上只是一个只引用内存位置的类型,因此您可以有2个引用相同对象实例的引用类型。 A&#34;值类型&#34;直接包含实际值,你不能通过修改不同的值类型搞乱一个值类型的值;它们是恰好具有相同价值的两个独立实例。但是,使用ref,您可以使值类型的行为与引用类型类似。

想想就像说,&#34;穿上第三个钩子&#34; - 这是一个参考。你知道外套在哪里,它是参考。如果你说,&#34;拿我的外套&#34;你确切知道你得到的外套(价值)。