我可以有一个基类,每个派生类都有自己的静态属性副本吗?

时间:2011-02-20 21:23:04

标签: c# inheritance derived-class base-class

我有以下情况:

class Base
{
     public static int x;
     public int myMethod()
     {
          x += 5;
          return x;
     }

}

class DerivedA : Base
{
}

class DerivedB : Base
{
}

我正在尝试设置它,以便每个派生类都有自己的x静态实例,如果我这样做的话:

 DerivedA.x = 5;
 DerivedB.x = 10;

然后当我跑:

 DerivedA.myMethod(); //The result will be 10
 DerivedB.myMethod(); //The reusult will be 15

我可以这样做吗?如何设置派生类来实现这一目标?谢谢你们。

编辑:基本上,我有一堆派生类,每个派生类都有一个独特的属性。它不会因每个实例而异,因此我认为应该是一个静态变量。此外,该属性由方法设置,对于每个类都是相同的。 我试图避免在每个派生类中复制和粘贴该属性和方法的逻辑。我认为最好以某种方式将该逻辑移动到从中派生每个类的基类。但是,我需要每个派生类都有自己的属性副本。 我不一定要这样做,如果你们有任何好的话,我会很高兴听到一些更好的做法建议..谢谢!

4 个答案:

答案 0 :(得分:10)

嗯,是的,你可以,但它围绕着泛型的一些技巧。

如果你修改你的设计以便你不需要那个静态字段,或者至少不是每个后代,那就更好了,但是这里有:

class Base<TDescendant>
    where TDescendant : Base
{
     public static int x;
     public int myMethod()
     {
          x += 5;
          return x;
     }

}

class DerivedA : Base<DerivedA>
{
}

class DerivedB : Base<DerivedB>
{
}

这取决于具有静态字段的泛型类型将为您调用它的每种类型获取这些静态字段的单独副本。

但是,如果你打算从DerivedA或DerivedB下降,它会变得棘手,所以我不建议你走这条路。

答案 1 :(得分:5)

您需要在所有派生类型中重新定义和隐藏字段和方法。

示例:

class DerivedA : Base
{
  public new static int x;
  public new int myMethod()
  {
    x += 5;
    return x;
  }
}

注意:不要这样做。修复你的设计。

编辑:

实际上,我有一个类似的结构。我用一个抽象(如果你需要一个默认值,使用virtual)属性来解决它,然后从基类中使用它:

public abstract class Base
{
   public abstract string Name { get; }

   public void Refresh()
   {
     //do something with Name
   }
}

public class DerivedA
{
  public override string Name { get { return "Overview"; } }
}

您应该能够针对您的用例进行调整。如果只有派生类应该能够看到它,你当然可以创建属性protected

答案 2 :(得分:1)

使用Type作为键的静态字典应该这样做。我的意思是避免逻辑重复和每个派生类型的不同值,但在实例之间共享。

public class Base
{
    private static Dictionatry<Type,int> _values;

    public int MyMethod()
    {
        _values[this.GetType()]+=5;
        return _values[this.GetType()];
    }
}

答案 3 :(得分:0)

我通常将子类特定的东西实现为抽象的get属性

public class Base
{
    // You must pick one option below

    // if you have a default value in the base class
    public virtual int x { get { return 7; /* magic default value */} }

    // if you don't have a default value
    // if you choose this alternative you must also make the Base class abstract
    public abstract int x { get; }
}

public class DerivedA : Base
{
    public override int x { get { return 5; } }
}

public class DerivedB : Base
{
    public override int x { get { return 10; } }
}