取3 ...
解決方案1:
我的首選方法是使用ICopyTo。我認爲它比其他任何東西都好,因爲它強制要有一個適當類型的對象來複制。它也同時進行克隆和複製。更容易維護。
還使用界面幫助做正確的事情。別忘了打電話給base.CopyTo ...
此外,我們可以說,CopyTo從是Fluent interface
public interface ICopyTo<T>
{
T CopyTo(T target);
}
public abstract class Person : ICopyTo<Person>, ICloneable
{
public Person CopyTo(Person person)
{
person.Age = Age;
person.Country = Country;
return person;
}
public abstract object Clone();
public int Age { get; set; }
public string Country { get; set; }
}
public abstract class Adult : Person, ICopyTo<Adult>, ICloneable
{
public Adult CopyTo(Adult adult)
{
base.CopyTo(this);
adult.Car = Car;
return adult;
}
public string Car { get; set; }
}
public class Man : Adult, ICopyTo<Man>, ICloneable
{
public Man CopyTo(Man man = null)
{
if (man == null)
{
man = new Man();
}
base.CopyTo(this);
man.Beer = Beer;
return man;
}
public string Beer { get; set; }
public override object Clone()
{
return CopyTo();
}
}
public class Woman : Adult, ICopyTo<Woman>, ICloneable
{
public Woman CopyTo(Woman woman = null)
{
if (woman == null)
{
woman = new Woman();
}
base.CopyTo(this);
woman.Purse = Purse;
return woman;
}
public string Purse { get; set; }
public override object Clone()
{
return CopyTo();
}
}
public class Test
{
public static void Go()
{
Man man1 = new Man() {Age = 10, Beer = "Bud", Country = "Canada"};
Man man2 = new Man();
man1.CopyTo(man2); // Real copy
Woman woman1 = new Woman() {Age = 32, Country = "USA", Purse = "Anything"};
Woman woman2 = woman1.CopyTo(); // Cloning
List<Person> adults = new List<Person>();
adults.Add(man1);
adults.Add(man2);
adults.Add(woman2);
Person person0 = adults[0].Clone() as Person;
Person person1 = adults[1].Clone() as Person;
Person person2 = adults[2].Clone() as Person;
}
}
解決方案2的部分:(只在基部類關閉到溶液1中,但與ICloneable)
public interface ICopyTo<T>
{
T CopyTo(T target);
}
public abstract class Person : ICopyTo<Person>, ICloneable
{
public virtual Person CopyTo(Person person)
{
if (person == null)
{
throw new ArgumentNullException("person can't be null");
}
person.Age = Age;
person.Country = Country;
return person;
}
public object Clone()
{
return CopyTo(null);
}
public int Age { get; set; }
public string Country { get; set; }
}
public abstract class Adult : Person, ICopyTo<Adult>, ICloneable
{
public Adult CopyTo(Adult adult)
{
if (adult == null)
{
throw new ArgumentNullException("adult can't be null");
}
base.CopyTo(this);
adult.Car = Car;
return adult;
}
public override Person CopyTo(Person person)
{
return CopyTo(person as Adult);
}
public string Car { get; set; }
}
public class Man : Adult, ICopyTo<Man>
{
public Man CopyTo(Man man = null)
{
if (man == null)
{
man = new Man();
}
base.CopyTo(this);
man.Beer = Beer;
return man;
}
public override Person CopyTo(Person person)
{
return CopyTo(person as Man);
}
public string Beer { get; set; }
}
public class Woman : Adult, ICopyTo<Woman>
{
public Woman CopyTo(Woman woman = null)
{
if (woman == null)
{
woman = new Woman();
}
base.CopyTo(this);
woman.Purse = Purse;
return woman;
}
public override Person CopyTo(Person person)
{
return CopyTo(person as Woman);
}
public string Purse { get; set; }
}
public class Test
{
public static void Go()
{
Man man1 = new Man() {Age = 10, Beer = "Bud", Country = "Canada"};
Man man2 = new Man();
man1.CopyTo(man2); // Real copy
Woman woman1 = new Woman() {Age = 32, Country = "USA", Purse = "Anything"};
Woman woman2 = woman1.CopyTo(); // Cloning
List<Person> adults = new List<Person>();
adults.Add(man1);
adults.Add(man2);
adults.Add(woman2);
Person person0 = adults[0].Clone() as Person;
Person person1 = adults[1].Clone() as Person;
Person person2 = adults[2].Clone() as Person;
}
}
解決方案3:
public static T Clone<T>(T source)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", "source");
}
// Don't serialize a null object, simply return the default for that object
if (Object.ReferenceEquals(source, null))
{
return default(T);
}
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream();
using (stream)
{
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}
對他們實現['ICloneable'](https://msdn.microsoft.com/en-us/library/system.icloneable(v = vs.110).aspx),這樣你的派生類也可以實現它,你只需要在基類上調用克隆來獲得派生類。 –
我可以選擇我想要克隆的屬性嗎?其中一些,如個人身份證號碼應該不同 – Sturm
*「ICloneable接口使您能夠提供一個自定義的實現,創建一個現有對象的副本。」*是的,您可以選擇想要在「克隆「方法。 –