2014-05-07 165 views
1

此代码的结果是“1”和“2”。当我将Foo“a”分开时,它会创建一个“b”实例,以及我对“b”所做的所有事情,它恰好也是“a”。 是否有任何解决方案可以给出完全独立的Foo实例?所以我的代码的结果将是“1”和“1”。克隆独立实例

using System.IO; 
using System; 
using System.Collections.Generic; 

class Program 
{ 
    static void Main() 
    { 

     Baar b0 = new Baar(); 
     Baar b1 = new Baar(); 
     Baar b2 = new Baar(); 
     Baar b3 = new Baar(); 
     Foo a = new Foo(200); 
     a.addBaar(b0); 

     Console.WriteLine(a.baars.Count); 
     Foo b = a.split(100); 

     b.addBaar(b1) ;  
     Console.WriteLine(a.baars.Count); 

    } 
} 

class Foo 
{ 
    public int amount; 
    public List<Baar> baars = new List<Baar>(); 
    public Foo(int amount) 
    { 
     this.amount = amount; 
    } 

    private Foo(int amount, List<Baar> baars) 
    { 
     this.amount = amount; 
     this.baars = baars; 
    } 

    public void addBaar(Baar baar) 
    { 
     this.baars.Add(baar); 

    } 

    public Foo split(int amount) 
    { 
     int diff = this.amount - amount; 
     this.amount = amount; 
     return new Foo(diff, this.baars); 
    } 
} 

class Baar 
{ 

    public Baar() 
    { 

    } 
} 
+2

“这段代码的结果是 ”1“ 和 ”2“。'...'所以我的代码的结果将是 ”1“ 和 ”2“。” - 是这些错误之一,还是你的代码已经做了你想要的? – Blorgbeard

+1

[Deep cloning objects]的可能重复(http://stackoverflow.com/questions/78536/deep-cloning-objects) –

+0

是的,这是一个错字。大声笑。我已纠正它。 – user3568719

回答

1

split你方法绕过到相同参考底层baars列表。这可以证明简单地:

List<int> a = new List<int>(); 
a.Add(1); 

Console.WriteLine(a.Count); //1 

List<int> b = a; 
b.Add(2); 

Console.WriteLine(b.Count); //2 
Console.WriteLine(a.Count); //2 
Console.WriteLine(Object.ReferenceEquals(a, b)); //true 

相反,你想传递的是列表的副本

public Foo split(int amount) 
{ 
    int diff = this.amount - amount; 
    this.amount = amount; 
    List<Baar> baarsCopy = new List<Baar>(this.baars); //make a copy 
    return new Foo(diff, baarsCopy); //pass the copy 
} 

编辑:除此之外,我不知道,如果你想该列表中的Baar项目的副本,或者传递/共享对同一个Baar实例的引用。这取决于您和您的应用程序使用情况。