C#内存管理(七)

一般来说,我们总是想克隆一个引用类型和拷贝一个值类型。记住这点将有助于你解决调试时发生的错误。让我们更进一步分析并清理一下Dude类实现,使用ICloneable接口来代替CopyDude()方法。

public class Dude : ICloneable {
  public string Name;
  public Shoe RightShoe;
  public Shoe LeftShoe;
  public override string ToString () {
    return (Name + " : Dude!, I have a " + RightShoe.Color +
      " shoe on my right foot, and a " +
       LeftShoe.Color + " on my left foot.");
  }
  #region ICloneable Members
  public object Clone () {
    Dude newPerson = new Dude();
    newPerson.Name = Name.Clone() as string;
    newPerson.LeftShoe = LeftShoe.Clone() as Shoe;
    newPerson.RightShoe = RightShoe.Clone() as Shoe;
    return newPerson;
  }
  #endregion
}

我们再来修改Main()中的方法:

public static void Main () {
  Class1 pgm = new Class1();
  Dude Bill = new Dude();
  Bill.Name = "Bill";
  Bill.LeftShoe = new Shoe();
  Bill.RightShoe = new Shoe();
  Bill.LeftShoe.Color = Bill.RightShoe.Color = "Blue";
  Dude Ted = Bill.Clone() as Dude;
  Ted.Name = "Ted";
  Ted.LeftShoe.Color = Ted.RightShoe.Color = "Red";
  Console.WriteLine(Bill.ToString());
  Console.WriteLine(Ted.ToString());
}

最后,运行我们的程序,会得到如下的输出:

Bill : Dude!, I have a Blue shoe on my right foot, and a Blue on my left foot.

Ted : Dude!, I have a Red shoe on my right foot, and a Red on my left foot.

还有些比较有意思的东西,比如System.String重载的操作符=号就实现了clones方法,因此你不用过于担心string类的引用复制问题。但是你要注意内存的消耗问题。如果你仔细查看上图,由于string是引用类型所以需要一个指针指向堆中的另一个对象,但是看起来它像是一个值类型。

你可能感兴趣的:(String,object,C#,Class)