【问题标题】:Is it possible to detect class context in an inherited static method?是否可以在继承的静态方法中检测类上下文?
【发布时间】:2009-09-09 15:10:33
【问题描述】:

好吧,这个标题有点不清楚,但我想不出更好的方式来表达它,除了解释它......

假设我有一个类Animal,带有一个静态的通用方法:

public static T Create<T>() where T : Animal {
  // stuff to create, initialize and return an animal of type T
}

我有子类DogCatHamster 等。为了得到Dog,我可以写:

Dog d = Animal.Create<Dog>();

Dog d = Dog.Create<Dog>();

这实际上是一回事。但是写Dog 这么多次似乎有点傻,因为我已经通过Dog 子类调用了静态方法。

你能想到在基类中编写Create() 方法以便我可以调用的任何巧妙方法

Dog d = Dog.Create();
Cat c = Cat.Create();
Hamster h = Hamster.Create();

不在每个子类中编写Create() 方法?

【问题讨论】:

    标签: c# generics inheritance


    【解决方案1】:

    您可以将 Animal 类设为泛型。

    class Animal<T> where T : Animal<T>
    {
        public static T Create()
        {
            // Don't know what you'll be able to do here
        }
    }
    
    class Dog : Animal<Dog>
    {
    
    }
    

    但是Animal 类如何知道如何创建派生类型的实例?

    【讨论】:

    • 您可能希望将 T 限制为 Animals:class Animal&lt;T&gt; where T : Animal&lt;T&gt;
    • Create() 中的代码将调用虚拟/抽象方法,这就是它创建派生类型实例的方式。
    • 实际上,我不得不再次发表评论,因为让 Animal 强制 T 成为 Animal 类型的想法纯粹是天才。乍一看,它看起来像无限递归,但事实并非如此;这是一个非常优雅的逻辑,让我的 HECKUVA 生活变得轻松多了。所以再次感谢 - 我希望我能投票给你更多! :)
    • 我正在为我的演示者使用这种约束,例如:interface IPresenter : IPresenter where TView : IView where TPresenter : IPresenter跨度>
    【解决方案2】:

    我会使用静态 Create 方法使 Animal 类抽象化;它实际上是工厂的起点。事实上,看起来您正在撤消工厂类。

    如果给Animal类添加抽象的Initialize方法,Create方法变成:

    public static T Create<T>() where T : Animal {
      T animal = new T();   //may need a "new" in the declaration
      animal.Initialize();  //or Create or whatever or you put this logic
                            //   in the constructor and don't call this at all.
      return animal;
    }
    

    【讨论】:

    • Animal 不能是静态类。但是,如果您想将创建委托给每个派生类型,最好将 Animal 设为抽象,并且将方法 Initialize 设为抽象而不是虚拟。
    • 好收获。那不是本意。
    • @Romain -- 好吧,我已经调整了答案。
    【解决方案3】:

    除了围绕它的其他答案之外,您可以使用反射看到 Create 始终仍然是 Animal 的一部分,而不是派生类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 2011-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多