[英]Use derived type in base abstract class
好吧,我有一些從基類派生的不同類。 此基類是包含commom方法的抽象。
其中一個方法是Copy
方法,它應該出現在所有派生類中,所以,我把它放在基類中。 但是,我希望它返回derived type
而不是基礎或對象。
我得到的解決方案是使用類型參數:
abstract class CopyableClass<T>
{
public abstract T Copy();
}
class DerivedClass : CopyableClass<DerivedClass>
{
public override DerivedClass Copy()
{
//do what is needed for copy and return a new DerivedClass
}
}
所以,這里的主要目的是
刪除基類中的type參數,仍然使該方法返回相應的派生類型。
一個解決方法。
到目前為止我能做的最好的事情是以下評論之一,但它仍然使用通用參數
abstract class BaseClass
{
//base methods not related to deriving type
}
interface ICopyable<T>
{
T Copy();
}
class DerivedClass : BaseClass, ICopyable<DerivedClass>
{
public DerivedClass Copy()
{
//do what is needed for copy and return a new DerivedClass
}
}
你不能真的。 基類不可能知道所有未來的實現。 您將不得不求助於通用抽象類(就像您所做的)類型或通用的Copy
方法。
public abstract class CopyableClass
{
public abstract T Copy<T>() where T : CopyableClass;
}
public class DerivedClass : CopyableClass
{
public override T Copy<T>()
{
if(typeof(T) != typeof(DerivedClass))
throw new ArgumentException();
// return your copy
}
}
或者,如果要在基類中概括類型檢查:
public abstract class CopyableClass
{
public T Copy<T>() where T : CopyableClass
{
if(GetType() != typeof(T))
throw new ArgumentException();
return (T) Copy();
}
protected abstract CopyableClass Copy();
}
public class DerivedClass : CopyableClass
{
protected override CopyableClass Copy()
{
return // Your copy;
}
}
請注意,第二種方法將大量信任放入派生類的實現中,因為它將盲目地轉換抽象方法的返回值。 編譯器將允許您在派生類型中返回另一個類型,實現CopyableClass,但它將是運行時錯誤。 如果您對所有派生實現具有絕對控制權(即您的抽象類也具有內部構造函數),則這不是問題。
您實際上想要在基類中實現副本並讓它返回T
這將使您使用類型參數調用它並返回該類型。
public static T Copy<T>() where T : CopyableClass
{
T retVal = new T();
// do whatever copying is required
return retVal;
}
打電話給你做;
DerivedClass d = Copy<DerivedClass>();
實際執行復制的代碼可能需要更多的工作來制作泛型,但是值得付出努力,因為您將擁有適用於任何派生類型的Copy()
的單個實現。 我不知道該方法中有什么邏輯,所以我只是把事情搞砸了。 另外,我建議一般檢查泛型。 對於像這樣的事情,它們通常是最好的選擇。 如果你的實現需要對基類是唯一的'保持相同的方法定義但是使它成為抽象,然后在基類中重寫它。
這將允許您將此基類置於派生類型並返回它。
public abstract class BaseClass<TDerived> : where TDerived: BaseClass<TDerived>
{
public TDerived DoSomethingCommon(string param)
{
var derivedType = (TElement)this;
//do something.
return derivedType;
}
}
這個解決方案涉及中產階級,但我認為它更符合您的需求。 至少你可以獲得隔離復制代碼的好處
public abstract class BaseClass
{
}
public abstract class CopyableClass<T> : BaseClass
where T: BaseClass, new()
{
public T Copy()
{
var copy = new T(); // Creating a new instance as proof of concept
return copy;
}
}
public class DerivedClass : CopyableClass<DerivedClass>
{
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.