可以从基本抽象类上的静态方法返回派生泛型类型吗?

时间:2012-06-24 22:13:55

标签: c# generics static abstract

抽象类:

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.

以上所有内容都可用,只是试图决定一项好的技术。

4 个答案:

答案 0 :(得分:0)

您无法使用静态方法执行此操作。我不确定你为什么要这样做,但你可以这样做

    public abstract class PersistentList<T>
    {
        public PersistentList<T> GetInstanceOfDerivedClass()
        {
            return (PersistentList<T>)Activator.CreateInstance(this.GetType());
        }
    }

<强>用法

Managers managers = (Managers)new Managers().GetInstanceOfDerivedClass();

答案 1 :(得分:0)

我认为这是最简单的,如果你需要强类型(即该方法将在请求Managers时返回PersistentList<Manager>而不仅仅是Managers):< / p>

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()中的签名。然而,我发现这种设计模式令人困惑,并且会阻止它的使用。

答案 2 :(得分:0)

这似乎是一个奇怪的情况,但假设你只是局限于这种模式,这是我能提出的最接近的事情(仍然不是你想要做的):

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>();

答案 3 :(得分:0)

可以使用您描述的模式,但在某些情况下,将工厂方法作为非泛型静态类中的泛型方法可能很有用,尤其是如果该方法将采用可用于的任何参数类型推断。例如,如果有一个方法来创建一个最初将从T[]填充的新集合,则在某些情况下使用SuperCollection<T> SuperCollection.Create<T>(T InitialValues[])SuperCollection<T> SuperCollection<T>.Create(T InitialValues[])更方便,因为前者可以根据数组参数的类型自动推断要创建的集合类型。

除此之外,我认为在所创建的对象类型可能取决于编译时可能不知道的各种因素的情况下,您所描述的是一种完全合理的模式。