Can I move the static access to the base class?

Refresh

December 2018

Views

97 time

1

I have a base and derived class like so:

public abstract class MyBase
{
   protected string _data;
   protected string GetData_Internal() {return _data;}
   protected abstract void SetData(string data);
}

public class MyDerived : MyBase
{
   protected override void SetData(string data) {_data = "my data";}

   public static string GetData()
   {
      var instance = new MyDerived();
      return instance.GetData_Internal();
   }
}

The desired usage of this class is like this:

string data1 = MyDerived.GetData();
string data2 = MyDerived2.GetData(); // another class dervied from MyBase

I can't make the classes static, because static classes and derived classes don't play well together. So I made the function GetData() static, and this allows me to use the class like I want to.

I am going to have multiple classes that all identical to MyDerived, except for the data values set in SetData().

I would like to move GetData() out of the derived class and into the base class so that I'm not duplicating that code in every single derived class.

I can't figure out how to do that, because a static method in the base class has no idea what type of object to new up.

So, is there any way to do what I'm trying to do, keeping a static interaction with the class, while avoiding code duplication to make it happen?

2 answers

4

If you are working with static data, maybe what you need are singleton objects that can be instantiated only once. They have the advantage of supporting inheritance and interface implementation, as well as being accessible statically. Also, unlike static classes, they can be passed as arguments to methods and stored in fields, properties and variables.

You can use properties instead of getter and setter methods. This simplifies your base class:

public abstract class MyBase
{
    public string Data { get; set; }
}

You can implement the singleton pattern like this:

public class MyDerived : MyBase
{
    #region Singleton Pattern

    public static readonly MyDerived Instance = new MyDerived();

    private MyDerived()
    {
    }

    #endregion
}

Create a public static readonly field that returns the only instance of the class and make the constructor private in order to forbid creating instances outside of the class itself. The constructor can also initialize the value of Data if required.

You can use the singletons like this:

MyDerived.Instance.Data = "my data";
string data = MyDerived.Instance.Data;

MyDerived2.Instance.Data = "my data 2";
...

See also: Implementing Singleton in C# for various ways of implementing the singleton pattern.

0

First, I am not completely sure what it is you are trying to accomplish. So, I am making no comment on if any of this is a good idea. You can get behavior that acts somewhat like overridden methods on base classes with statics. Instead, you overwrite the base then call into it. I do something similar to this for fetching instances or collections of instances from the class:

public class Dog
{
    public static Dog GetById(int dogId) 
    { 
        //Return dog 
    }
}

public class Lab : Dog
{
    public new static Lab GetById(int dogId) 
    { 
        //Return same dog, as a lab 
    }
}

A quick and terrible, but hopefully useful, version might start like the following. I might be able to make it into something practical if I understand your intentions a bit better.

public abstract class MyBase
{
    public static string GetData()
    {
        return "BASE STUFF";
    }
}

public class MyDerivedA : MyBase
{
    protected const string MySpecialData = "AAAAAA";

    public new static string GetData()
    {
        return MyBase.GetData() + MySpecialData;
    }
}

public class MyDerivedB : MyBase
{
    protected const string MySpecialData = "BBBBBBB";

    public new static string GetData()
    {
        return MyBase.GetData() + MySpecialData;
    }
}