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

发布于 2024-07-08 22:35:59 字数 322 浏览 15 评论 0原文

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

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

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

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

In a C# program, I have an abstract base class with a static "Create" method. The Create method is used to create an instance of the class and store it locally for later use. 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.

Are there any facilities within the C# language that will allow me to pull this off. My current fallback position is to pass an instance of the derived class as one of the arguments to the Create function, i.e.:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

尴尬癌患者 2024-07-15 22:35:59

尝试使用泛型:

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

示例使用:

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

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>();
翻身的咸鱼 2024-07-15 22:35:59

摘要

有两个主要选项。 更好、更新的一种是使用泛型,另一种是使用反射。 如果您需要开发一个在 .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));

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.

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));
空‖城人不在 2024-07-15 22:35:59

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

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

这是你想要的吗?

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 ?

酒废 2024-07-15 22:35:59

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

Sounds like you need to make the Create() method abstract. 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.

救星 2024-07-15 22:35:59

没有外部信息你就无法做到这一点; 派生类的类型、派生类的实例或派生类的完全限定名称。 其中任何一个都相当于你已经在做的事情; 据我所知,没有更好的解决方案。 静态方法的本质不允许任何更优雅的方法。

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.

叫思念不要吵 2024-07-15 22:35:59

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

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

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.

I think if you look at using an IoC container it will solve your problem in a much cleaner and loosely coupled way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文