0
我想創建一個類層次結構,其中一個BaseClass.GetCopy()
方法將提供相同的運行時子類的副本,具有相同的只讀ID屬性(通過構造函數傳遞),並與每一個公共可寫屬性複製。深層複製涉及參數的構造函數
我得到了下面的代碼,但測試沒有通過,因爲我不知道如何實現基於反射的特性複製。此外,在基類的構造函數成爲重複(錯誤傾向,IMO),並且已設置一個是公開的,這是不是在這種情況下,是一件好事,因爲我不希望客戶端代碼,可以設置IDS明確。
我的問題被表述爲在下面的代碼註釋:
[TestFixture]
public class RepoItemTests
{
[Test]
public void CloneHasSameId()
{
var one = new ConcreteRepoItemName();
var two = one.GetCopy();
Assert.AreEqual(one.Id, two.Id);
}
[Test]
public void CloneIsSubclassInstance()
{
var one = new ConcreteRepoItemAge();
var two = one.GetCopy();
Assert.IsInstanceOf<ConcreteRepoItemAge>(two);
}
[Test]
public void ChangingCloneNameDoesntChangeOriginalAge()
{
var one = new ConcreteRepoItemName() { Name = "original" };
var two = one.GetCopy() as ConcreteRepoItemName;
Assert.AreEqual(one.Name, two.Name);
two.Name = "modified";
Assert.AreNotEqual(one.Name, two.Name);
}
[Test]
public void ChangingCloneAgeDoesntChangeOriginalAge()
{
var one = new ConcreteRepoItemAge() { Age = 22 };
var two = one.GetCopy() as ConcreteRepoItemAge;
Assert.AreEqual(one.Age, two.Age);
two.Age = 33;
Assert.AreNotEqual(one.Age, two.Age);
}
}
public class ConcreteRepoItemName : AbstractRepoItem<ConcreteRepoItemName>
{
public ConcreteRepoItemName() : base() { }
// I don't want the constructor below to be public
public ConcreteRepoItemName(Guid id) : base(id) { }
public string Name { get; set; }
}
public class ConcreteRepoItemAge : AbstractRepoItem<ConcreteRepoItemAge>
{
public ConcreteRepoItemAge() : base() { }
// I don't want the constructor below to be public
public ConcreteRepoItemAge(Guid id) : base(id) { }
public decimal Age { get; set; }
}
public abstract class AbstractRepoItem<T> where T : AbstractRepoItem<T>, new()
{
public AbstractRepoItem()
{
Id = Guid.NewGuid();
}
// I don't want the constructor below to be public
protected AbstractRepoItem(Guid id)
{
Id = id;
}
public Guid Id { get; private set; }
public T GetCopy()
{
var clone = Activator.CreateInstance(typeof(T), new object[] { Id }) as T;
/// HOW DO I COPY RUNTIME PROPERTIES HERE VIA REFLECTION?
return clone;
}
}
將您的類標記爲可序列化,您可以通過序列化和反序列化來創建深層副本。沒有其他代碼需要。 –