C# Clone函数重写

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# Clone函数重写相关的知识,希望对你有一定的参考价值。

using System;
namespace Wrox.ProCSharp.Basic

class CloneTest

static void Main()

string[] names="Lily","John","Ian";
string[] namesClone=(string[])names.Clone();
namesClone[2]="June";
foreach(string name in names)

Console.WriteLine("0",name);


foreach(string name in namesClone)

Console.WriteLine("0",name);


Person Test=new Person("Lily",16);
Person TestClone=(Person)Test.Clone();
Test.age=19;
Console.WriteLine("0,1",Test.name,Test.age);
Console.WriteLine("01",TestClone.name,TestClone.age);





class Person

public string name;
public int age;
public Person(string name,int age)

this.name=name;
this.age=age;





编译提示perison类不包含Clone定义
1、是不是自定义类使用Clone函数就必须重写Clone函数?
2、应该如何改写

1、定义类时声明:class person:ICloneable
2、克隆包括浅复制和深复制,甚至可以不复制(但没有意义了),你的person类中要实现以下方法:
public object Clone()

//return this as object;//不复制,引用同一个对象
return this.MemberwiseClone(); //浅复制
//return new person() as object;//深复制

不复制时是引用同一个对象,二者的变化一致是关联的!
浅复制和深复制都是对对象的复制,区别在于:深复制会复制整个填充的对象,包括该对象中其他引用类型和值类型的值;而浅复制只复制了一个对象中所有引用,它没有值的复制,通过引用它们的其他对象的引用来共享它们。
针对你的类用浅复制就可以了。
参考技术A 1.在Person类上集成ICloneable 接口并实现上面的object Clone()方法;c#在基类object没有定义Clone();方法;

2.
public object Clone()
Person p=new Person();
p.name=this.name;
p.age=this.age;
return p;

java克隆clone()方法和相等equals()方法的重写

1、为什么要重写clone()方法?

Java中的浅度复制是不会把要复制的那个对象的引用对象重新开辟一个新的引用空间,当我们需要深度复制的时候,这个时候我们就要重写clone()方法。

 

2、equals()和clone()方法重载的示例

Hourse类:

import java.util.Date;

public class House implements Cloneable {
     
        private int id;
        private double area;
        private Date whenBulit;
        House(){
        }
        House(int newId,double newArea){
            id = newId;
            area = newArea;
            whenBulit = new Date();
        }
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public void setArea(double area) {
            this.area = area;
        } 
        public void setWhenBulit(long whenBulit) {
           this.whenBulit.setTime(whenBulit) ;
        }    
        public double getArea() {
            return area;
        }
        public Date getWhenBulit() {
            return whenBulit;
        }
        public long getWhenBulitTime() {
            return whenBulit.getTime();
        }
       //重写equals方法,因为我们要对比的是date类中的时间而不是对象的引用地址
        public boolean equals(House obj){
            //obj.getArea()==this.getArea()
            //obj.getId()==this.getId();
            //obj.getWhenBuildTime==this.getWhenBuildTime()
            if(obj.getArea()==this.getArea()&&obj.getId()==this.getId()&&obj.getWhenBulitTime()==this.getWhenBulitTime())
              return true;
            else
            {
                return false;
            }
        }
        //如果重载了equals方法,按照规范也应该重载hashCode(),这里只是简单了将hashCode和传入的id关联起来
        @Override
        public int hashCode(){
            return getId();
        }
        public Object clone() throws CloneNotSupportedException{
            //构造一个对象 house,并且使用id和area
            House house = new House(this.getId(),this.getArea());
            //调用对象中的setWhenBuild方法,使用getTime()可以获得一个毫秒数。
            house.setWhenBulit(this.getWhenBulit().getTime()) ;
            return house ;
        }
    }

 

Testor类:

public class Testor {
     public static void main(String[] args ) throws CloneNotSupportedException{
            House h1 = new House(1,200.0);
            House h2 = (House)h1.clone();
            
            System.out.println(h1==h2);
            
            System.out.println(h1.equals(h2));
            
            System.out.println(h1.getWhenBulit()== h2.getWhenBulit());
            
            System.out.println(h1.getWhenBulit().equals(h2.getWhenBulit()));
        }
}

3、API中clone()方法介绍的疑惑

在API1.6中看见这样一句话:

般情况下:

    x.clone().equals(x)

为 true,但这并非必须要满足的要求。

这里需要注意,如果我们这样调用代码测试:

public class TestClone implements Cloneable {

    public static void main(String []args) throws CloneNotSupportedException{
        TestClone tc=new TestClone();
        try{
        Object obj=tc.clone();
        System.out.println(obj==tc);//结果是false
        System.out.println(obj.equals(tc));//结果是false
        }catch(Exception e){
            System.out.println("Exception:"+e.getMessage());
        }
    }
}

那么结果就是false。因为equals默认条件是比较变量中引用地址的值,API上的意思是如果我们需要使用Clone()方法,那么在重载的时候一般情况下应该在重写equals()方法,不需要比较对象的引用,只需要将重写的代码写为比较对象的值就符合了。

 

以上是关于C# Clone函数重写的主要内容,如果未能解决你的问题,请参考以下文章

java克隆clone()方法和相等equals()方法的重写

C# 保存文件 - (删除并重写?)

转载 [c#] 虚函数(Virtual),抽象函数(abstract)和接口的区别

用 C# 重写 MFC DLL?

一文读懂C#中的抽象类抽象方法virtual虚函数override重写函数及父类子类构造函数和析构函数的执行顺序

23种设计模式 - 原型模式