Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 这个IClonable实现有什么问题吗_C# - Fatal编程技术网

C# 这个IClonable实现有什么问题吗

C# 这个IClonable实现有什么问题吗,c#,C#,我没有用C语言编程,但我儿子问我这个实现是否有什么问题 public class Person : A, IClonable { .... public object Clone() { return this; } } 我的直觉是这是错误的,因为这个Clone()方法实现不返回任何新对象。我认为Clone()方法应该创建一个新对象,或者调用一个创建新对象的方法,然后返回它。这就是我对儿子说的,但由于没有做任何C#编程,我变得不确定。有人能解释一下吗 我的直觉是

我没有用C语言编程,但我儿子问我这个实现是否有什么问题

public class Person : A, IClonable {
....

    public object Clone() {
       return this;
    }
}
我的直觉是这是错误的,因为这个Clone()方法实现不返回任何新对象。我认为Clone()方法应该创建一个新对象,或者调用一个创建新对象的方法,然后返回它。这就是我对儿子说的,但由于没有做任何C#编程,我变得不确定。有人能解释一下吗

我的直觉是这是错误的,因为这个Clone()方法 实现不返回任何新对象

那种感觉骗不了你。如果要创建新对象的副本,则需要创建新对象。否则,它只是同一个引用,而这个实现是毫无意义和误导性的

假设您的类有一个
StringProperty

Person p1 = new Person{ StringProperty = "Foo" };
Person p2 = (Person)p1.Clone();
p2.StringProperty = "Bah";
Console.Write(p1.StringProperty); // "Bah"
您可以看到,即使我更改了
p2
上的属性,我也会修改另一个实例的
StringProperty
,因为它实际上是相同的

所以你需要这样的东西:

public object Clone() {
    Person p2 = new Person();
    p2.StringProperty = this.StringProperty;
    // ...
    return p2;
}
尽管我更喜欢创建一个不同的方法
Copy
,因为通常不清楚
Clone
的作用。甚至微软也建议不要实施
ICloneable


接口是合同。如果您的类实现了iClonable,则它:

支持克隆,这将创建与现有实例具有相同值的类的新实例

现在,如果
Clone(){return this;}
的编写者或使用此代码的任何其他人依赖返回值作为原始对象的克隆,并对原始对象进行了一些可能尚未进行的修改,则您需要跟踪一个bug。

读取并检查

我认为你是对的——你不会创建新的对象,因此如果你想克隆并更改对象,他会更改原始对象,这不是预期的

请注意,该对象并不特别是深度或浅层副本


它只是指定它应该复制。而此实现没有。要克隆对象,请尝试此方法

方法1:

public class Person : ICloneable
{
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public Address PersonAddress { get; set; }

    public object Clone()
    {
        Person newPerson = (Person)this.MemberwiseClone();
        newPerson.PersonAddress = (Address)this.PersonAddress.Clone();

        return newPerson;
    }
}

public class Address : ICloneable
{
    public int HouseNumber { get; set; }
    public string StreetName { get; set; }

    public object Clone()
    {
        return this.MemberwiseClone();
    }
}
public class Person : ICloneable
{
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public Address PersonAddress { get; set; }

    public object Clone()
    {
        object objResult = null;
        using (MemoryStream ms = new MemoryStream())
        {
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(ms, this);

            ms.Position = 0;
            objResult = bf.Deserialize(ms);
        }
        return objResult;
    }
}
public class Person : ICloneable
    {
        public string LastName { get; set; }
        public string FirstName { get; set; }
        public Address PersonAddress { get; set; }

        public object Clone()
        {
            var objResult = new Person();
            objResult.LastName = this.LastName;
            objResult.FirstName = this.FirstName;
            objResult.PersonAddress = new Address();
            objResult.PersonAddress.HouseNumber = this.PersonAddress.HouseNumber;
            objResult.PersonAddress.StreetName = this.PersonAddress.StreetName;

            return objResult;
        }
    }
方法2:

public class Person : ICloneable
{
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public Address PersonAddress { get; set; }

    public object Clone()
    {
        Person newPerson = (Person)this.MemberwiseClone();
        newPerson.PersonAddress = (Address)this.PersonAddress.Clone();

        return newPerson;
    }
}

public class Address : ICloneable
{
    public int HouseNumber { get; set; }
    public string StreetName { get; set; }

    public object Clone()
    {
        return this.MemberwiseClone();
    }
}
public class Person : ICloneable
{
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public Address PersonAddress { get; set; }

    public object Clone()
    {
        object objResult = null;
        using (MemoryStream ms = new MemoryStream())
        {
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(ms, this);

            ms.Position = 0;
            objResult = bf.Deserialize(ms);
        }
        return objResult;
    }
}
public class Person : ICloneable
    {
        public string LastName { get; set; }
        public string FirstName { get; set; }
        public Address PersonAddress { get; set; }

        public object Clone()
        {
            var objResult = new Person();
            objResult.LastName = this.LastName;
            objResult.FirstName = this.FirstName;
            objResult.PersonAddress = new Address();
            objResult.PersonAddress.HouseNumber = this.PersonAddress.HouseNumber;
            objResult.PersonAddress.StreetName = this.PersonAddress.StreetName;

            return objResult;
        }
    }
方法3:

public class Person : ICloneable
{
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public Address PersonAddress { get; set; }

    public object Clone()
    {
        Person newPerson = (Person)this.MemberwiseClone();
        newPerson.PersonAddress = (Address)this.PersonAddress.Clone();

        return newPerson;
    }
}

public class Address : ICloneable
{
    public int HouseNumber { get; set; }
    public string StreetName { get; set; }

    public object Clone()
    {
        return this.MemberwiseClone();
    }
}
public class Person : ICloneable
{
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public Address PersonAddress { get; set; }

    public object Clone()
    {
        object objResult = null;
        using (MemoryStream ms = new MemoryStream())
        {
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(ms, this);

            ms.Position = 0;
            objResult = bf.Deserialize(ms);
        }
        return objResult;
    }
}
public class Person : ICloneable
    {
        public string LastName { get; set; }
        public string FirstName { get; set; }
        public Address PersonAddress { get; set; }

        public object Clone()
        {
            var objResult = new Person();
            objResult.LastName = this.LastName;
            objResult.FirstName = this.FirstName;
            objResult.PersonAddress = new Address();
            objResult.PersonAddress.HouseNumber = this.PersonAddress.HouseNumber;
            objResult.PersonAddress.StreetName = this.PersonAddress.StreetName;

            return objResult;
        }
    }

你说得对:该方法应该创建一个新对象。这不是对IClonable的引用