【问题标题】:C#: Determine derived object type from a base class static methodC#:从基类静态方法确定派生对象类型
【发布时间】:2010-09-22 22:42:11
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: c# static-methods derived-class


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 静态成员不能标记为abstract,非静态成员对此无用;如果您可以调用 new DerivedFoo(),那么您显然不需要原始帖子要求的内容。
      【解决方案3】:

      尝试使用泛型:

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

      使用示例:

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

      【讨论】:

        【解决方案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>();
            }
         }     
        

        这是你想要的吗?

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            【解决方案6】:

            总结

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

            【讨论】:

              猜你喜欢
              • 2011-03-05
              • 2012-05-24
              • 2010-10-10
              • 1970-01-01
              • 2015-04-08
              • 2013-01-10
              • 2013-03-28
              • 1970-01-01
              • 2021-09-10
              相关资源
              最近更新 更多