![](/img/trans.png)
[英]Constrain generic type on a method to be any class that is derived from any variant form of an abstract generic base class
[英]Can a derived generic type be returned from a static method on the base abstract class?
抽象類:
abstract class PersistentList<T>
public static PersistentList<T> GetInstanceOfDerivedClass()
{
//???
}
派生類:
public class Managers : PersistentList<Manager>
因此,我想:
Managers managers = Managers.GetInstanceOfDerivedClass();
那可能嗎?
選擇是:
int clientID = 3;
Managers managers = Managers.For("Client", new { ClientID = clientID});
Managers managers = new Managers(new { ClientID = clientID });
Managers managers = new Managers();
managers.ClientID = clientID;
managers.Load("ForClient");
//alternatively:
Database.Load(managers, "ForClient");
//this works, however requires the above code in the constructor.
Managers managers = new Managers(clientID);
//If the static method on the abstract class (Managers.For) could determine
//the type calling, it would eliminate the need for repetitive constructors.
以上都是可用的,只是試圖決定一種好的技術。
您不能使用靜態方法來執行此操作。 我不確定為什么要這么做,但是您可以這樣做
public abstract class PersistentList<T>
{
public PersistentList<T> GetInstanceOfDerivedClass()
{
return (PersistentList<T>)Activator.CreateInstance(this.GetType());
}
}
用法
Managers managers = (Managers)new Managers().GetInstanceOfDerivedClass();
我認為這是最簡單的,如果您需要強類型化(即,該方法將在請求Managers
時返回Managers
,而不僅僅是PersistentList<Manager>
):
static class PersistentList
{
public static T GetInstanceOfDerivedClass<T, U>() where T : PersistentList<U>
{
throw new NotImplementedException();
}
}
Managers managers = PersistentList.GetInstanceOfDerivedClass<Managers, Manager>();
您可能還會這樣做:
abstract class PersistentList<T, U> where T : PersistentList<T, U>
{
public static T GetInstanceOfDerivedClass()
{
throw new NotImplementedException();
}
}
public class Managers : PersistentList<Managers, Manager>
{
}
這使您可以在示例中使用簽名Managers.GetInstanceOfDerivedClass()
。 但是,我發現這種設計模式令人困惑,並且會阻止其使用。
這似乎是一種奇怪的情況,但是假設您被某種方式限制在這種模式下,這是我能想到的最接近的方法(仍然不完全是您要嘗試做的事情):
abstract class PersistentList<T>
{
public static T2 GetInstanceOfDerivedClass<T2>() where T2 : PersistentList<T>
{
return (T2)Activator.CreateInstance(typeof(T2));
}
}
class Manager { }
class Managers : PersistentList<Manager> { }
用法:
Managers managers = PersistentList<Manager>.GetInstanceOfDerivedClass<Managers>();
可以使用您所描述的模式,但是在某些情況下,將工廠方法作為非泛型靜態類中的泛型方法可能會很有用,尤其是如果該方法將采用任何可用於類型推斷的參數時。 例如,如果有一種方法可以創建一個新集合,該方法最初是從T[]
填充的,那么在某些情況下,使用SuperCollection<T> SuperCollection.Create<T>(T InitialValues[])
可能會更方便。而不是SuperCollection<T> SuperCollection<T>.Create(T InitialValues[])
,因為前者可以根據數組參數的類型自動推斷要創建的集合的類型。
除此之外,在所創建的對象類型可能取決於編譯時可能未知的各種因素的情況下,我認為您所描述的是一種完全合理的模式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.