让一个类将自己作为参数传递给泛型基类邪恶?

Joh*_*son 16 c# oop generics design-patterns

我第一次看到一位同事在实施对象池时这样做了.他将要作为参数汇集的类传递给泛型基类.这个基类列出了池代码.

奇怪的是基类会知道它的孩子.在每种正常情况下,这被认为是不好的做法.但在这种情况下,父母只是避免编写重复代码的技术解决方案.任何其他代码都不会引用基类.

这种结构的一个缺点是它"烧掉了基础类".您不能在层次结构的中间引入通用基类.此问题可能超出了主题范围.

以下是一个可以想象的例子:

public abstract class Singleton<T> where T : class
{
    public static T Instance { get; private set; }

    public Singleton()
    {
        if (Instance != null)
            throw new Exception("Singleton instance already created.");
        Instance = (T) (object) this;
    }
}

public class MyClass : Singleton<MyClass>
{
}
Run Code Online (Sandbox Code Playgroud)

改进代码:

public abstract class Singleton<T> where T : Singleton<T>
{
    public static T Instance { get; private set; }

    public Singleton()
    {
        if (Instance != null)
            throw new Exception("Singleton instance already created.");
        Instance = (T) this;
    }
}

public class MyClass : Singleton<MyClass>
{
}
Run Code Online (Sandbox Code Playgroud)

SLa*_*aks 14

没有; 这是一种众所周知的模式,称为CRTP.
它在C++中作为虚拟方法的替代方法特别有用.

你可以在IComparable<T>和.Net框架中看到它IEquatable<T>.

为了增加稳健性,您应该添加 where T : Singleton<T>

  • 另请参阅以下讨论,声明它与C++ CRTP不同:http://stackoverflow.com/questions/16142620/what-does-this-parameter-type-constraint-mean (2认同)