C#:从基类静态方法确定派生对象类型

时间:2008-11-18 21:20:45

标签: c# static-methods derived-class

在C#程序中,我有一个带有静态“Create”方法的抽象基类。 Create方法用于创建类的实例并将其存储在本地以供以后使用。由于基类是抽象的,因此实现对象总是从它派生。

我希望能够从基类派生一个对象,通过派生类调用静态Create方法(在基类中实现一次),并创建派生对象的实例。

C#语言中是否有任何设施允许我将其关闭。我目前的后备位置是将派生类的一个实例作为Create函数的一个参数传递,即:

objDerived.Create(new objDerived(), "Arg1", "Arg2");

6 个答案:

答案 0 :(得分:12)

尝试使用泛型:

public static BaseClass Create<T>() where T : BaseClass, new()
{
    T newVar = new T();
    // Do something with newVar
    return T;
}

样品使用:

DerivedClass d = BaseClass.Create<DerivedClass>();

答案 1 :(得分:5)

摘要

有两个主要选择。更好更新的是使用泛型,另一种是使用反射。如果您需要开发一个在.NET 2.0之前工作的解决方案,我将提供这两种方法。

泛型

abstract class BaseClass
{
  public static BaseClass Create<T>() where T : BaseClass, new()
  {
    return new T();
  }
}

用法如下:

DerivedClass derivedInstance = BaseClass.Create<DerivedClass>();

反射

abstract class BaseClass
{
  public static BaseClass Create(Type derivedType)
  {
    // Cast will throw at runtime if the created class
    // doesn't derive from BaseClass.
    return (BaseClass)Activator.CreateInstance(derivedType);
  }
}

使用的位置(为了便于阅读,分为两行):

DerivedClass derivedClass
    = (DerivedClass)BaseClass.Create(typeof(DerivedClass));

答案 2 :(得分:4)

您想在抽象基类上使用静态工厂方法创建从另一个派生实例派生的新实例吗?如果是这样,我想知道为什么......但是......

 public abstract class MyBase
 {
    public static T GetNewDerived<T>() where T : MyBase, new()
    {
        return new T();
    }    
 }
 public class DerivedA : MyBase
 {
    public static DerivedA GetNewDerived()
    {
        return GetNewDerived<DerivedA>();
    }
 }

 public class DerivedB : MyBase
 {
    public static DerivedB GetNewDerived()
    {
        return GetNewDerived<DerivedB>();
    }
 }     

这是你想要的吗?

答案 3 :(得分:3)

听起来你需要使Create()方法变得抽象。一旦你这样做,你也可以重命名它,并使它成为构造函数。然后,如果需要,可以在构造对象后调用不同的Init()方法,并且正常的多态效果将处理事物。

答案 4 :(得分:1)

没有外界信息你不能这样做;要么派生类的类型,它的实例,还是派生类的完全限定名称。任何这些都等同于你已经在做的事情;我知道没有更好的解决方案。静态方法的本质排除了任何更优雅的东西。

答案 5 :(得分:0)

我不确定你的设计目标是什么,但是从你的问题来看,它可能最终会带来很多代码味道。我认为你应该深入研究在许多框架中实现的控制反转(IoC)/依赖注入(DI)设计模式,例如Microsoft Unity,Castle Windsor,StructureMap,Ninject,Spring.Net等。

我认为如果您考虑使用IoC容器,它将以更清洁和松散耦合的方式解决您的问题。