평론net 플랫폼에서 깊이 복사와 얕은 복사

7770 단어
기본 개념:
평론 복사: 대상의 필드가 복사되고 필드가 인용하는 대상은 복사되지 않으며 복사 대상과 원 대상은 인용 명칭만 다르지만 하나의 실체를 공용한다.어떤 대상에 대한 변화도 다른 대상에게 영향을 줄 수 있다.대부분의 인용 유형은 얕은 복사를 실현한다. 인용 유형의 대상 간의 값은 하나의 대상 인용 주소의 복사본을 복제하는 것이고 가리키는 대상의 실례는 여전히 같다.
깊이 복사: 대상의 하위 세그먼트가 복사되고 필드에서 인용된 대상도 복사되는 것을 말한다.심층 복사는 전체 원본 대상의 구조를 만들고 복사 대상과 원 대상은 서로 독립되며 어떠한 실례 데이터도 공유하지 않으며 한 대상을 수정하면 다른 대상에게 영향을 주지 않는다.값 유형 간의 값 부여 작업은 깊은 복사를 실행합니다.
기본 개념의 참조 코드:
 
  
class Program
    {
        static void Main(string[] args)
        {
            Student s1 = new Student("li", 23);

            //
            Student s2 = s1;
            s2.Age = 27;
            s1.ShowInfo();//li's age is 27

            //
            int i = 12;
            int j = i;
            j = 22;
            Console.WriteLine(i);//12

            Console.Read();
        }
    }

    class Student
    {
        public string Name;
        public int Age;

        public Student(string name, int age)
        {
            Name = name;
            Age = age;
        }

        public void ShowInfo()
        {
            Console.WriteLine("{0}'s age is {1}", Name, Age);
        }
    }


분석:
상례에서 실례 s2는 s1에 대해 얕은 복사를 했고 s2의 Age 필드를 변경했다. 이어서 실례 s1의 Age 필드에 영향을 주었다.
깊은 복사본에서, 단지 값 유형 간의 간단한 값일 뿐, 'j' 에 대한 변경은 'i' 의 값을 변경하지 않습니다.
깊이 있는 복제본 구현:
 
  
public object Clone()
{
return this.MemberwiseClone();
}

MemberwiseClone: 간단한 테이블 복사본을 생성합니다.새 객체를 만들고 현재 객체의 비정상적인 필드를 새 객체로 복사하는 절차입니다.필드가 값 유형이면 필드를 한 위치씩 복사하고 필드가 참조 유형이면 참조를 복사하지만 참조 객체는 복사하지 않습니다.
참조 코드:
 
  
class Program
    {
        static void Main(string[] args)
        {
            ClassA ca = new ClassA();
            ca.value = 88;
            ClassA ca2 = new ClassA();
            ca2 = (ClassA)ca.Clone();
            ca2.value = 99;
            Console.WriteLine(ca.value + "-----" + ca2.value);//88---99

            ClassB cb = new ClassB();
            cb.Member.value = 13;

            ClassB cb2 = (ClassB)cb.Clone();
            cb2.Member.value = 7;
            Console.WriteLine(cb.Member.value.ToString() + "------" + cb2.Member.value.ToString());// :7---7      :13----7          

            Console.Read();
        }
    }

    public class ClassA : ICloneable
    {
        public int value = 0;

        public object Clone()
        {
            return this.MemberwiseClone();
        }
    }

    public class ClassB : ICloneable
    {
        public ClassA Member = new ClassA();

        public object Clone()
        {
            //
            return this.MemberwiseClone();

            //
            ClassB obj = new ClassB();
            obj.Member = (ClassA)Member.Clone();
            return obj;
        }
    }


분석:
상례에서ca2는ca대상을 복제하여 심도 있는 복사를 실현하였다.결과는 코드와 같습니다:ca2 중치 형식 필드의 변화는ca의 필드에 영향을 주지 않습니다.
클래스ClassB에서 유형 구성원 Member를 인용하는데 ClassA의clone 방법으로 실현하면 얕은 복사만 실현할 수 있다. 상기 참고 코드에서 알 수 있듯이 cb2의member에 대한 변화가 cb에 영향을 미친다.그러나 참고 코드의 깊이 있는 복사를 사용한 후 cb2의member에 대한 변화는 cb에 영향을 주지 않는다.
인터넷에서 심도 있는 복사를 설명하기 위해 대비된 예를 찾아라.
인스턴스 1:
 
  
public class Sex:ICloneable
    {
        private string _PSex;
        public string PSex
        {
            set{ _PSex = value;}
            get { return _PSex; }
        }

        //public object Clone()
        //{
        //    return this.MemberwiseClone();
        //}
    }

    public class Person : ICloneable
    {

        private Sex sex = new Sex();
        public int aa = 3;

        public string pSex
        {
            set { sex.PSex = value; }
            get { return sex.PSex; }
        }
        private string _PName;
        public string PName
        {
            set { this._PName = value; }
            get { return this._PName; }
        }

        public void ShowPersonInfo()
        {
            Console.WriteLine("-------------------------");
            Console.WriteLine("Name:{0} Sex:{1}", _PName, this.pSex);
            Console.WriteLine("-------------------------");
            Console.WriteLine(this.aa);
        }
        //
        public object Clone()
        {
            return this.MemberwiseClone();
        }
        //
        public object DeepClone()
        {
            Person newP = new Person();
            newP.PName = this._PName;
            newP.pSex = this.pSex;
            return newP;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(" :");
            Person p = new Person();
            p.PName = "Lee";
            p.pSex = " ";

            p.ShowPersonInfo();// :lee 3

            //        
            Person copy = (Person)p.Clone();
            //
            Person dcopy = (Person)p.DeepClone();

            Console.WriteLine(" :");
            p.PName = "Zhao";
            p.pSex = " ";
            p.aa = 1;
            p.ShowPersonInfo();//zhao 1

            Console.WriteLine(" :");
            copy.ShowPersonInfo();//lee 3

            Console.WriteLine(" :");
            dcopy.ShowPersonInfo();//lee 3

            Console.WriteLine(" :");
            Person PP = p;
            PP.ShowPersonInfo();//zhao 1

            Console.ReadLine();
        }
    }


분석:
먼저 위의 예에서 클래스 Sex에 Clone 메서드를 추가하고 추가하지 않는 것은 인스턴스의 연산 결과에 영향을 미치지 않는다는 점을 고려해야 합니다.
클래스 Person에서 인용 유형은string 유형의 Pname 필드이고 인용 유형 pSex 필드이며 값 유형 aa입니다.
초기값:lee남3(먼저 깊이 복사)
값 수정:zhao 여자 1
얕은 복사치:lee녀3
딥 카피 값:lee 남3
직접 복사치: 조녀1
결과: 상술한 것은 심도 있는 복사에서 자주 만나는 몇 가지 유형에 대해 총괄하고 대비한 것이라고 할 수 있으며 깨달은 후에 지식을 배울 수 있을 것이라고 믿는다.
인스턴스 2:
 
  
class Program
    {
        static void Main(string[] args)
        {
            int[] numbers = { 2, 3, 4, 5 };
            int[] numbersCopy = new int[5];
            numbers.CopyTo(numbersCopy, 0);
            numbersCopy[2] = 0;

            int[] numbers1 = { 2, 3, 4, 5 };
            int[] numbersClone1 = (int[])numbers1.Clone();
            numbersClone1[2] = 0;

            Console.Write(numbers[2] + "---" + numbersCopy[2]);//4---0
            Console.Write(numbers1[2] + "---" + numbersClone1[2]);//4--0


            // ,
            int[] numbers2 = { 2, 3, 4, 5 };
            int[] numbers2Copy = numbers2;
            numbers2Copy[2] = 0;

            Console.Write(numbers2[2]);//0
            Console.Write(numbers2Copy[2]);//0

            Console.Read();
        }
    }


잠시 분석을 하지 않고 진지하게 깨닫다.

좋은 웹페이지 즐겨찾기