c# - 引用另一个引用类型的引用类型

时间:2010-12-19 17:37:02

标签: c# variable-assignment reference-type

注意:这适用于List和ArrayList

看看以下简单代码:

class Creature
{
    public string Name;
}

class Game
{
    // This is a reference type
    public Creature CurrentCreature;
}

class Program
{
   static void Main(string[] args)
   {
        // First, we'll create 2 objects and let the 
        // reference type "CurrentCreature" points to one of them
        Creature dragon = new Creature();
        dragon.Name = "Dragon";        

        Creature Unicorn = new Creature();
        dragon.Name = "Unicorn";

        Game game = new Game();
        game.CurrentCreature = dragon;

        // Now we'll create a list which will contain
        // the reference type "CurrentCreature"
        List<Creature> list = new List<Creature>();                
        list.Add(game.CurrentCreature);

        foreach (Creature c in list)
        {
            Console.WriteLine(c.Name);    // Output is "Dragon"
        }

        // Now, we'll let "CurrentCreature" point to a different object
        game.CurrentCreature = unicorn;

        // The reference in the list still pointing to the original object!!!
        foreach (Creature c in list)
        {
            Console.WriteLine(c.Name);   // Output is "Dragon"!!! 
        }

        Console.ReadLine();
   }
}

我检查了列表如何添加项目,并且没有新对象的实例化。这是List.Add方法(使用Reflector工具)

   public void Add(T item)
        {
            if (this._size == this._items.Length)
            {
                this.EnsureCapacity(this._size + 1);
            }
            this._items[this._size++] = item;   // No instantiation
            this._version++;
        }

那么,为什么会这样呢?列表中的元素应该是对“CurrentCreature”指向的对象的引用,还是不是?如果我们删除列表,它是否与以下代码类似?:

class A
{
    public B X;
}
class B
{
    public string Name;
}
....

A a = new A();
B b1 = new B(); b1.Name = "b1";
B b2 = new B(); b2.Name = "b2";
a.X = b1;

Console.WriteLine(a.X.Name); // output: b1
b1 = b2;
Console.WriteLine(a.X.Name); // output: b1

3 个答案:

答案 0 :(得分:2)

当你这样做时

game.CurrentCreature = unicorn;

将game.CurrentCreature中的指针覆盖为unicorn对象。该数组仍然有一个指向龙对象的指针。它不应该被改变,这就是指针的工作方式。

编辑:

对指针发生的事情的一点解释:

首先你创建了2个对象

Creature dragon = new Creature();
dragon.Name = "Dragon";        

Creature Unicorn = new Creature();
dragon.Name = "Unicorn";

这使龙有一个指向龙对象的指针,而独角兽有一个指向你的独角兽对象的指针。

然后你将game.CurrentCreature的指针设置为龙的指针。

game.CurrentCreature = dragon;

然后你将指向当前生物龙的指针添加到列表中

List<Creature> list = new List<Creature>();                
list.Add(game.CurrentCreature);

然后用指向独角兽对象的指针替换game.CurrentCreature(龙)中的指针。

game.CurrentCreature = unicorn;

这绝不会影响龙对象中的指针。

干杯,

答案 1 :(得分:1)

参考类型不只是改变。

您将该生物添加到列表中,而不是游戏中。然后你改变游戏的参考来使用anoter creature;但是列表中引用的生物保持不变,因此它会再次输出相同的结果。

答案 2 :(得分:0)

参考被复制到列表中,而不是对象。在list.Add(myobject);之后,您将获得两个引用(指向同一个对象):myobject和列表中的那些引用。