5

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

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

C# 语言中是否有任何工具可以让我完成这项工作。我当前的后备位置是将派生类的实例作为参数之一传递给 Create 函数,即:

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

6 回答 6

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>();
于 2008-11-18T21:35:15.183 回答
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));
于 2008-11-18T22:17:46.253 回答
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>();
    }
 }     

这是你想要的吗 ?

于 2008-11-18T21:46:42.540 回答
3

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

于 2008-11-18T21:24:53.910 回答
1

如果没有外部信息,您将无法做到;派生类的类型、它的实例或派生类的完全限定名称。这些中的任何一个都等同于您已经在做的事情;我知道没有更好的解决方案。静态方法的本质排除了任何更优雅的东西。

于 2008-11-18T21:22:46.143 回答
0

我不确定您的设计目标是什么,但根据您的要求,这听起来可能最终会产生很多代码气味。我认为您应该真正研究在 Microsoft Unity、Castle Windsor、StructureMap、Ninject、Spring.Net 等众多框架中实现的控制反转 (IoC) / 依赖注入 (DI) 设计模式。

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

于 2008-11-18T21:50:27.057 回答