派生静态成员

时间:2008-12-05 16:18:32

标签: c# design-patterns oop

我有一个具有私有静态成员的基类:

class Base
{
    private static Base m_instance = new Base();
    public static Base Instance
    {
        get { return m_instance; }
    }
}

我想从中派生出多个类:

class DerivedA : Base {}
class DerivedB : Base {}
class DerivedC : Base {}

但是,此时调用DerivedA :: Instance将返回与DerivedB :: Instance和DerivedC :: Instance相同的确切对象。我可以通过在派生类中声明实例来解决这个问题,但是然后每个派生类都需要这样做,而且看起来它应该是不必要的。那么有什么方法可以将所有这些放在基类中吗?可以应用设计模式吗?

3 个答案:

答案 0 :(得分:11)

这样做有一种非常好的方式:

class Base
{
     // Put common stuff in here...
}

class Base<T> : Base where T : Base<T>, new()
{
    private static T m_instance = new T();

    public static T Instance { get { return m_instance; } }
}

class DerivedA : Base<DerivedA> {}
class DerivedB : Base<DerivedB> {}
class DerivedC : Base<DerivedC> {}

这是有效的,因为每个构造类型有一个静态变量 - 例如List<string>List<int>的类型不同,因此会有单独的静态变量。

我也抓住机会将它作为派生类的一个实例 - 我不知道这是不是你想要的,但我认为我至少可以为你提供它:)< / p>

总的来说,这是一件令人讨厌的事情。静态变量并不是真正为这种用途而设计的 - 我只是滥用了泛型的特性来获得你所要求的“某种”行为。

另请注意,Base<DerivedA>.Instance将返回与DerivedA.Instance相同的结果 - 属性/变量不会“知道”您正在使用DerivedA.Instance。我不知道这对你来说是否重要。

使用额外的非泛型类,您可以写:

Base t = DerivedA.Instance;
t = DerivedB.Instance;

如果您不需要,请将其取出:)

答案 1 :(得分:6)

静态方法不支持多态,因此,这样的事情是不可能的。

从根本上说,Instance属性不知道你是如何使用它的。并且它的单个实现将存在,因为它是静态的。如果您真的想这样做,可以使用这种“不推荐”的解决方案(我从Jon的解决方案中得到了想法):

private static Dictionary<Type, Base> instances = new Dictionary<Type, Base>();
public static T GetInstance<T>() where T : Base, new() {
  Type ty = typeof(T);
  T x;
  if (instances.TryGetValue(ty, out x)) return x;
  x = new T();
  instances[ty] = x;
  return x;
}

答案 2 :(得分:3)

简短回答:不是我知道的。静态成员总是非虚拟的,不容易支持多态。

但是,你也应该问自己为什么你这样做。通常,静态成员是共享资源,该类的每个实例(包括派生类)都会发现它们很有用。但是,当您创建静态实例时,通常会构建为单例模式。在这种情况下,您通常希望密封类,以便您不能拥有派生类,从而使整个点无意义。因此,您应该真正分析为什么要这样做并改为解决问题。