在阅读C#入门经典的时候(第218页) 
有下面一代码 public void Shuffle()//洗牌程序 

    Card[] newDeck = new Card[52]; 
    bool[] assigned = new bool[52]; 
    Random sourceGen = new Random(); 
    for ( int i = 0; i < 52; i++ ) 
    { 
        int destCard = 0; 
        bool foundCard = false; 
        while (foundCard == false) 
        { 
            destCard = sourceGen.Nest(52); 
    if (assigned[destCard] == false) 
    { 
foundCard = true; 
    } 
    assigned[destCard] = true; 
    newDeck[destCard] = cards[i]; 

newDeck.CoptyTo(cards, 0); //为什么不用cards=newDeck呢? 
} 上面的函数把数组里的每个Card对象(每张牌)的位置打乱 书上说,如果使用cards= newDeck,就会用另一个对象替代cards引用的对象实例。如果其他地方的代码仍保留对原cards实例的引用,就会出问题——不会洗牌 我的理解是如果用cards=newDeck的话,cards会指向newDeck所在的区域,而newDeck只是一个局部变量,在Shuffle方法外面可能被修改,那么cards会出现不可预期的内容。(这个比不会洗牌严重很多,感觉书中没有说到问题的关键)。我只是一个新手,不知道这样理解对不对?敬请大家指教!

解决方案 »

  1.   

    我觉得就这个方法本身而言,用直接赋值也可以,因为虽然两个变量指向同一块内存,但是只有cards可以在该方法外部被访问,而newDeck变量是局部变量,在赋值语句之后就没有用到了。所以没有什么关系。
      

  2.   

    问题是,newDeck为局部变量,在方法调用完毕后,newDeck应该会被释放,其所指向的区域会不会被修改呢?
      

  3.   

    我也是新手,猜想不知对否:
    因为在.net里,并不是用完之后,就马上被释放到了,而是要等所有引用都完了,才会被回收机制处理,所以这个不会有问题。
      

  4.   

    其他地方的代码仍保留对原cards实例的引用,就会出问题——不会洗牌 
    这句话怎么理解呢?newDeck.CoptyTo(cards, 0)和cards=newDeck 会有一样的效果啊,感觉
      

  5.   

    newDeck.CoptyTo(cards, 0)
    是指把 newDeck复制到 cards处。cards=newDeck
    是把newDeck的引用给cards所以原来引用cards的地方,还是没有变,变的只是cards的引用不知是不是这样,请大家确认。
      

  6.   

    我觉得newDeck.CoptyTo(cards, 0),是把cards所指的内存区域改为了NewDeck,而cards=newDeck是把cards指向了newDeck内存区域,但是我觉得不存在书中所说的问题啊。
    “其他地方的代码仍保留对原cards实例的引用,就会出问题——不会洗牌 ”还请高手们帮忙看看
      

  7.   

    new出来的对象,是当没有被引用的时候,才被回收释放的。
    newDeck是局部,但它所指向的内存对象,如果有其它引用(例如cards),就不会被释放。cards指向(可以当指针看)外部的对象,暂时叫A
    函数内,newDeck指向了一块跟A一样的,new出来的内存B,然后洗牌,就是把B给洗了如果newDeck.CoptyTo(cards, 0),就是把B复制一份给A,这时A改变了,函数退出,B的引用newDeck
    没了,B也就跟着被回收了(实际上不一定马上回收,反正你已经没有它的引用了)如果cards=newDeck,就是把cards也指向B,这时A没有改变,函数退出,newDeck没了,但cards还在
    所以B仍然在。
    这时,如果函数外部一直用cards来处理这批数据(B),就不会有事。
    但,如果外部本来有其它变量是指向A的,那就会出问题了,因为现在有2份牌,一份A,由其它变量引用,
    一份B,由cards引用(newDeck已经死了)
      

  8.   

    抱歉,楼上仓促作答,没细看代码,后来究竟了一下,实际上有所出入。那2份 A和B,并不是52个card对象,而是2份 52个的数组引用。
    cards指向第一份引用数组A(52个引用,顺序)
    newDeck指向第二份引用数组B(52个引用,乱序)
    如果用 cards = newDeck,只是把 cards 也指向了B,效果来说,cards也乱序了,但如果外部有其它变量指向A,那就会有书中提到的问题了。
    如果用CopyTo,就是把B复制一份给A,这样A也乱序了,即使其它变量指向A,也会得到乱序的数组。
      

  9.   

    思考了N久,总算有结果了,图片无法上传,还是直接访问我的链接
    http://hi.baidu.com/leezjnu/blog/item/b9f470135b94204ff2de32e6.html
      

  10.   

    楼上解释正确,我画了一幅图,可以更加清晰的解释http://hi.baidu.com/leezjnu/blog/item/b9f470135b94204ff2de32e6.html