【问题标题】:C# containers initialized by reference or value?通过引用或值初始化的 C# 容器?
【发布时间】:2013-02-03 05:01:50
【问题描述】:

我熟悉 C++,但对 C# 有点陌生。

将对象添加到容器时,它们是通过引用传递还是通过值传递?

也就是说,如果我这样做:

myClass m = new myClass(0);       //Assume the class just holds an int
List<myClass> myList = new List<myClass>(1);
myList.Add(m);
myList[0] += 1;
Console.WriteLine(m);
Console.WriteLine(myList[0]);

结果会是:

0
1

还是会

1
1

?

如果是前者,那我怎样才能让它做后者呢?我的第一直觉是做类似的事情

myClass ref mref = m; 
Console.WriteLine(mref);

但这似乎不是有效的语法。

【问题讨论】:

  • “结果会是这样吗?” - 自己尝试并不难!顺便说一句……
  • 除了你从未说过,你的myClass 是 - 引用或值类型
  • 我假设这里是引用类型
  • @Andy:你要解决的实际问题是什么......???
  • 我有一个我正在编程的游戏的怪物数组,我正在尝试用健康> 0的怪物填充字典,使用整数键,以便我可以显示键值和当前的健康并允许用户选择一个,然后立即开始修改它。我希望更改渗透到原始阵列中的怪物。我知道还有更多迂回的方法可以做到这一点,但我想知道这是否可能。

标签: c# reference containers


【解决方案1】:

将值按值传递给Add方法;然而,如果你传递一个引用类型(一个类总是一个引用类型),那么值本身就是一个引用。所以问题不在于值是通过值传递还是通过引用传递,而是类型是值类型还是引用类型。

class MyClass
{
    public int Number { get; set; }
}

通过这个声明,我们得到:

MyClass m = new MyClass();
List<MyClass> myList = new List<MyClass>();
myList.Add(m);

myList[0].Number += 1;
Console.WriteLine(myList[0].Number); // Displays 1
Console.WriteLine(m.Number); // Displays 1

myList[0].Number += 1;
Console.WriteLine(myList[0].Number); // Displays 2
Console.WriteLine(m.Number); // Displays 2

请注意,这不适用于struct,因为myList[0] 返回的值将是存储在列表中的值的副本。 += 1 只会增加这个临时副本的Number 属性,因此除了消耗几个处理器周期之外没有其他影响。因此,最好只创建不可变结构。


如果要直接显示对象,覆盖ToString

class MyClass
{
    public int Number { get; set; }

    public override string ToString()
    {
        return Number.ToString();
    }
}

现在,你可以写了

myList[0].Number += 1;
Console.WriteLine(myList[0]);
Console.WriteLine(m);

您甚至可以让myList[0] += 1 使用运算符重载。在MyClass声明

public static MyClass operator +(MyClass m, int i) 
{
    m.Number += i;
    return m;
}

但这有点奇怪,除非您的类表示一个数字,但在这种情况下,不可变的 struct 会更受欢迎,因为数字通常被视为不可变的值类型。

public static MyStruct operator +(MyStruct m, int i) 
{
    return new MyStruct(m.Number + i);
}

【讨论】:

  • 谢谢,这就是我想要了解的。我应该更清楚地表述事情——我的例子是否有效不是我想要的——你的答案就是我想要的。
猜你喜欢
  • 2013-07-28
  • 1970-01-01
  • 1970-01-01
  • 2016-05-04
  • 2013-10-10
  • 1970-01-01
  • 1970-01-01
  • 2020-04-19
  • 2021-08-21
相关资源
最近更新 更多