简体   繁体   English

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

[英]C#: Determine derived object type from a base class static method

In a C# program, I have an abstract base class with a static "Create" method. 在C#程序中,我有一个带有静态“Create”方法的抽象基类。 The Create method is used to create an instance of the class and store it locally for later use. Create方法用于创建类的实例并将其存储在本地以供以后使用。 Since the base class is abstract, implementation objects will always derive from it. 由于基类是抽象的,因此实现对象总是从它派生。

I want to be able to derive an object from the base class, call the static Create method (implemented once in the base class) through the derived class, and create an instance of the derived object. 我希望能够从基类派生一个对象,通过派生类调用静态Create方法(在基类中实现一次),并创建派生对象的实例。

Are there any facilities within the C# language that will allow me to pull this off. C#语言中是否有任何设施可以让我解决这个问题。 My current fallback position is to pass an instance of the derived class as one of the arguments to the Create function, ie: 我当前的后备位置是将派生类的实例作为Create函数的参数之一传递,即:

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

Try using generics: 尝试使用泛型:

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

Sample use: 样品用途:

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

Summary 摘要

There are two main options. 有两个主要选择。 The nicer and newer one is to use generics, the other is to use reflection. 更好更新的是使用泛型,另一种是使用反射。 I'm providing both in case you need to develop a solution that works prior to .NET 2.0. 我提供这两个以防你需要开发一个在.NET 2.0之前工作的解决方案。

Generics 泛型

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

Where the usage would be: 用法如下:

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

Reflection 反射

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

Where the usage would be (split over two lines for readability): 使用的位置(为了便于阅读,分为两行):

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

You want to create a new instance of derived from inside another instance of derived, using a static factory method on the abstract base class? 您想在抽象基类上使用静态工厂方法创建从另一个派生实例派生的新实例吗? if so, I wonder Why... But ... 如果是这样,我想知道为什么......但......

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

Is this what you want ? 这是你想要的吗 ?

Sounds like you need to make the Create() method abstract. 听起来你需要使Create()方法成为抽象。 And once you do that you might as well rename it and make it the constructor as well. 一旦你这样做,你也可以重命名它,并使它成为构造函数。 Then you can have a different Init() method that you call after the object is constructed if you need to, and normal polymorphism effects will handle things. 然后,如果需要,可以在构造对象后调用不同的Init()方法,并且正常的多态效果将处理事物。

You can't do it without outside information; 没有外界信息你就做不到; either the type of the derived class, an instance of it, or the fully-qualified name of the derived class. 要么派生类的类型,它的实例,还是派生类的完全限定名称。 Any of these are equivalent to what you're already doing; 任何这些都等同于你已经在做的事情; there isn't a better solution I'm aware of. 我知道没有更好的解决方案。 The very nature of static methods precludes anything more elegant. 静态方法的本质排除了任何更优雅的东西。

I'm not sure what your design goals are but from what you asked it sounds like it might end up with alot of code smell. 我不确定你的设计目标是什么,但是从你的问题来看,它可能最终会带来很多代码味道。 I think you should really look into the Inversion of Control(IoC) / Dependency Injection (DI) design patterns that are implemented in numerous frameworks such as Microsoft Unity, Castle Windsor, StructureMap, Ninject, Spring.Net and so forth. 我认为你应该真正研究在许多框架中实现的控制反转(IoC)/依赖注入(DI)设计模式,例如Microsoft Unity,Castle Windsor,StructureMap,Ninject,Spring.Net等等。

I think if you look at using an IoC container it will solve your problem in a much cleaner and loosely coupled way. 我想如果你看一下使用IoC容器,它将以更清洁和松散耦合的方式解决你的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM