using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace employees
{
    class Employee : ICloneable
    {
        private readonly int propId;
        private String propFirst;
        private String propLast;        public Employee(int id)
        {
            if (id > 9999 || id < 1000)
                throw new Exception("Invalid Employee ID");            propId = id;
        }
        public String FullName
        {
            get
            {
                return propFirst + " " + propLast;
            }
        }        public String First
        {
            get
            {
                return propFirst;
            }
            set
            {
                propFirst = value;
            }
        }        public String Last
        {
            get
            {
                return propLast;
            }
            set
            {
                propLast = value;
            }
        }        public int EmplID
        {
            get
            {
                return propId;
            }
        }        public Object Clone()
        {
            return this.MemberwiseClone();
        }        public override string ToString()
        {
            return FullName;
        }
    }    class Program
    {
        static void Main(string[] args)
        {
            Employee obj1 = new Employee(3242);
            Employee obj2 = (Employee)obj1.Clone() ;
            obj1.Last = "Marshall";
            obj2.First = "Donis";
            Console.WriteLine(obj1.EmplID + " : " + obj1.FullName);
            Console.WriteLine(obj2.EmplID + " : " + obj2.FullName);
        }
    }
}
这段程序按照MemberWiseClone()的浅拷贝定义,应该是输出
3242 : Donis Marshall
3242 :  Donis Marshall
但是我在vs2010中运行结果是:
3242 : Marshall
3242 :  Donis
这是为什么?还有C#中的object和Object有什么区别,string和String的区别呢,仅仅是一个是值类型一个引用类型吗?

解决方案 »

  1.   

    这2个属性修改为:public String First
    {
        get
        {
            Console.WriteLine("Get First");
            return propFirst;
        }
        set
        {
            Console.WriteLine("Set First");
            propFirst = value;
        }
    }public String Last
    {
        get
        {
            Console.WriteLine("Get Last");
            return propLast;
        }
        set
        {
            Console.WriteLine("Set Last");
            propLast = value;
        }
    }输出:
    Set Last
    Set First
    3242 :  Marshall
    3242 : Donis你明白了?
      

  2.   


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Drawing;class TestClass
    {
        public int x=0;
        public int y=0;
    }class Employee : ICloneable
    {
        private readonly int propId;
        private String propFirst;
        private String propLast;
        private TestClass test;    public Employee(int id)
        {
            if (id > 9999 || id < 1000)
                throw new Exception("Invalid Employee ID");        propId = id;
        }
        public String FullName
        {
            get
            {
                return propFirst + " " + propLast;
            }
        }    public String First
        {
            get
            {
                Console.WriteLine("Get First");
                return propFirst;
            }
            set
            {
                Console.WriteLine("Set First");
                propFirst = value;
            }
        }    public String Last
        {
            get
            {
                Console.WriteLine("Get Last");
                return propLast;
            }
            set
            {
                Console.WriteLine("Set Last");
                propLast = value;
            }
        }    public int EmplID
        {
            get
            {
                return propId;
            }
        }    public TestClass Test
        {
            get { return test; }
            set { test = value; }
        }    public Object Clone()
        {
            return this.MemberwiseClone();
        }    public override string ToString()
        {
            return FullName;
        }
    }public class Class3
    {
        public static void Test()
        {
            Employee obj1 = new Employee(3242);        
            obj1.Last = "Marshall";
            obj1.Test = new TestClass() { x = 1, y = 1 };        Employee obj2 = (Employee)obj1.Clone();
            obj2.First = "Donis";
            obj2.Test.x = 2;
            obj2.Test.y = 2;
            Console.WriteLine(obj1.EmplID + " : " + obj1.FullName + " test : " + obj1.Test.x.ToString() + "," + obj1.Test.y.ToString());
            Console.WriteLine(obj2.EmplID + " : " + obj2.FullName + " test : " + obj2.Test.x.ToString() + "," + obj2.Test.y.ToString());
        }
    }string是特殊类型,赋值操作将会使得引用指向另一个字符串池中的对象。Test引用类型,就是你期望的结果。
      

  3.   

    this.MemberwiseClone()这个方法对于值类型是逐个复制,对于引用类型则复制引用但不复制引用对象(也就是说复制引用类型的对象指向同一地址).
    楼主没有理解浅复制原型设计模式
    Employee obj1 = new Employee(3242);
    Employee obj2 = (Employee)obj1.Clone() ;
    这两个是不同的地址.obj2的修改不会影响obj1。怎么可能得到相同的值呢!你可以测试一下
    Console.WriteLine(obj1==obj2);是否为True 就知道原因了!而这个
     Employee obj2 = (Employee)obj1.Clone();
            obj2.First = "Donis";
            obj2.Test.x = 2;
            obj2.Test.y = 2;
    当中的obj2.Text是个引用类型。
    所以obj2.Test.x = 2;
        obj2.Test.y = 2;这样复制只是对同一个对象修改,故能得到相同的值
      

  4.   

    谢谢。我是初学C#。那浅复制原型设计模式是什么样的?怎么样才让obj1he obj2有相同的地址?
      

  5.   

    原型设计模式有两种: 浅复制和深复制两种。你可以看看http://terrylee.cnblogs.com/archive/2006/01/16/317896.html 或者看看<<大话设计模式>>