[英]How do I write a general method to copy instances of classes that all inherit from the same abstract base class?
我想按照以下代碼將一個畫筆實例的詳細信息復制到一個新實例:
private static Brush CopyBrush(Brush b)
{
Brush b1 = new Brush();
// code to copy settings from b to b1
return b1;
}
我的困難是Brush是一個抽象類,因此我無法實例化它。 我有許多不同的類繼承自Brush,可以將其中的任何一個都傳遞給此方法。 繼承類都在Brush中使用相同的屬性,因此復制它們不是問題。 可以在調用源將返回值強制轉換回繼承類型。
如果保證所有派生類都具有帶有特定簽名的構造函數(例如,不帶任何參數),則可以基於其子Type
實例實例化各自的子Type
:
Brush b1 = (Brush)Activator.CreateInstance(b.GetType());
如果不能保證這一點,則需要在Brush
類中引入虛擬方法來創建當前類的新實例。 子類可以重寫它以調用合適的構造函數。
更具體地說,您的Brush
類可以具有以下方法:
protected virtual Brush CreateBrushInstance()
{
return (Brush)Activator.CreateInstance(GetType());
}
在需要不同構造函數參數的任何派生類中,重寫此方法並使用適當的參數值調用Activator.Create(Type, object[])
方法 。
(這假定CopyBrush
是Brush
類的方法。否則,對CreateBrushInstance
方法使用internal
或public
可見性。)
情況1:您所有從Brush
派生的類都有一個公共的默認構造函數,而所有屬性都有一個公共的setter。
在這種情況下,一個通用方法就足夠了:
static TBrush Copy<TBrush>(this TBrush brush) where TBrush : Brush, new()
{
return new TBrush() // <- possible due to the `new()` constraint ^^^
{
TypeOfHair = brush.TypeOfHair,
NumberOfHairs = brush.NumberOfHairs,
…
};
}
情況2:不滿足上述一個或多個前提條件; 也就是說,沒有公共默認構造函數,或者至少一個屬性是不可公開設置的。
您可以使用以下模式:
abstract class Brush
{
protected abstract Brush PrepareCopy();
// replacement for public default ctor; prepares a copy of the derived brush
// where all private members have been copied into the new, returned instance.
public Brush Copy()
{
// (1) let the derived class prepare a copy of itself with all inaccessible
// members copied:
Brush copy = PrepareCopy();
// (2) let's copy the remaining publicly settable properties:
copy.TypeOfHair = this.TypeOfHair;
copy.NumberOfHairs = this.NumberOfHairs;
return copy;
}
}
sealed class FooBrush : Brush
{
public FooBrush(int somethingPrivate)
{
this.somethingPrivate = somethingPrivate;
// might initialise other members here…
}
private readonly int somethingPrivate;
protected override Brush PrepareCopy()
{
return new FooBrush(somethingPrivate);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.