5

I have something like the following situation below:

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

}

class DerivedA : Base
{
}

class DerivedB : Base
{
}

I am trying to set this up so that each derived class has its own static instance of x, if I do something like this:

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

then when I run:

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

Can i do something like this? How can I setup the derived classes to achieve this? Thanks guys.

EDIT: Basically, I have a bunch of derived classes that each have a property unique to that class. It does not vary for each instance, and thus I believe should be a static variable. Also, that property is set by a method, that is the same for each of these classes. I am trying to avoid having to copy and paste the logic for that property and method in each of these derived classes. I thought it best to somehow move that logic to the base class from which each of these classes are derived from. But, I need each derived class to have its own copy of that property. I do not necessarily have to do it this way, and I will be happy to hear some better practices suggestions if you guys have any.. Thanks!

ntsue
  • 2,325
  • 8
  • 34
  • 53

4 Answers4

12

Well, yes, you can, but it revolves around a bit of a trick with generics.

It is much better if you fix your design so that you don't need that static field, or at least not per descendant, but here goes:

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>
{
}

This relies on the fact that a generic type with static fields will get a separate copy of those static fields for each type you invoke it with.

However, if you intend to descend from DerivedA or DerivedB, it gets tricky, so I wouldn't recommend going down this lane.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
  • I chose to implement this pattern for what I believe to be a legit pattern. I welcome feedback. My static property is one which contains a static list of token replacement mappings. Each email type has its own class, which inherits from a base class. The classes are used in the processing of emails - the email template has tokens in it which are replaced with actual values at run time. The tokens don't change, so I use a static property: private static Dictionary _TokenReplacementMappings = new Dictionary() {...}; – Vince Horst Apr 03 '14 at 17:44
  • I Prefer this method too. – Tejasvi Hegde Mar 13 '15 at 05:44
  • But for multi level inheritence, one need to mix and match with with techniques like this and the above one. – Tejasvi Hegde Mar 13 '15 at 05:55
  • Thanks for the insight. I had completely forgotten that generic types create a new copy of static fields. Like you said though, this can quickly get tricky if care is not taken. – Alex Essilfie Aug 20 '15 at 03:32
5

You will need to redefine and hide the field and method in all derived types.

Example:

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

Note: don't do it this way. Fix your design.

Edit:

Actually, I have a similar construct. I solve it with an abstract (if you need a default value, use virtual) property which then gets used from the base class:

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"; } }
}

You should be able to adjust that for your use case. You can of course make the property protected if only deriving classes should be able to see it.

Femaref
  • 60,705
  • 7
  • 138
  • 176
  • So, what is the best way to avoid repeating code in each of my derived classes? The method would be the same for each of my derived classes. – ntsue Feb 20 '11 at 21:37
  • 1
    Please edit your question to display what you want to achieve. We will be able to help you more that way. – Femaref Feb 20 '11 at 21:39
  • So, I took the code you gave and modified it by adding a private static variable to DerivedA... and I use the overridden property to get and set that static field... Is that ok? Or is that not a good way to do it? It seems to do what I want.. thanks!! – ntsue Feb 21 '11 at 14:41
  • Well, the point is to not use any static field at all - you should use just the property on its own. The point is that you don't have to add a static field everytime you derive but simply override the property and handle your case there. – Femaref Feb 21 '11 at 14:44
  • If I don't use a static field, and I just use the property.. wouldn't every instance of DerivedA have it's own copy of "Name"? I wanted the entire class to share a copy of "Name". Forgive me if I am not understanding correctly... Thanks! – ntsue Feb 21 '11 at 15:16
  • Yes it would, but what is the problem with that? Fact is, you can't require a class to implement a static field. However, you can require a class to implement a public or protected property. A small price to pay to have this desire to have the information required by code rather than by documentation. – Femaref Feb 21 '11 at 15:21
1

Static dictionary with Type as keys should do. I mean avoid logic repetition and different values for each derived type but shared among instances.

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

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

I usually implement subclass specific stuff as an abstract get property

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; } }
}
Albin Sunnanbo
  • 46,430
  • 8
  • 69
  • 108