4

I am developing a project in C# and due to a design decision it is not possible to have a static class inherit another static class. But I have, in my opinion, a case where this would make sense.

I have a music player which is able to play music from many different music sources: local files, YouTube, SoundCloud, Jamendo, etc. I have currently one static class for each of these sources with static methods such as retrieving the top tracks, searching for tracks, etc.

Naturally, a lot of code is shared among all these classes so I wanted to refactor and put all common code into a more generic MusicSource class. But C# doesn't allow me to do that.

What would be the best practice here? I want to get rid of all my redundant code and make it easier to create new music sources.

  • 2
    Given that you have countless static classes already.. why are you now considering inheritance? Why not just add a another common static class and call that from the others? – Simon Whitehead Jul 12 '13 at 8:41
  • 1
    Why do you think you need inheritance? Why can't you group the redundant code into a static class and call it from your Music Source static classes? – user2313838 Jul 12 '13 at 13:23
16

Those "music source" classes sound more like non-static classes which you happen to only want one instance of. They are two different things!

Here are some reasons why you might want to make them non-static:

  • If they have (or might eventually have) some internal state. e.g. Cached login credentials, or cached lists of the top 10 tracks. Stateful static classes are a bad idea! They are basically a poor implementation of a singleton.
  • If you're going to have a lot of music sources, you may well want to perform some actions on all of them. e.g. Find a particular track from any source. With static classes you're going to need a line for each class. If you've got non-static classes you can just loop over a collection of them.

There's a great answer here which gives more reasons and goes into more detail.

3

It is not possible to inherit static classes at all (at least in C#), regardless of any 'design decision'.

Perhaps your question needs rephrasing, but can you not use non-static classes like in this contrived and overly simple example;

abstract class MusicSource 
{  
    abstract MusicData LoadMusic(string source);

    protected string SomeCommonProperty { get; set; }
}

class JamendoSource : MusicSource 
{   
    override MusicData LoadMusic(string source)
    {
        // Jamendo-specific code
    }
}
  • By "design decision" I was referring to the decision by Mads Torgersen. – Christoffer Reijer Jul 18 '13 at 5:27
  • There's nothing todo whith his decisions. .NET does not support static inheritance... – Frederik P. Jul 18 '13 at 6:07
1

Using static in this case is completely wrong. People tend to use static's way to often! Basicly you have 1 "MusicPlayer" with X-amount of implementation (youtube, ...) So the first thing that should pop up in your head is inheritance.

They will all do the same, but abit different => Inheritance. You want your application to work with several kinds of sources, without any need to adapt the application itself => Inheritance/Interface segregation.

Static classes can be useful, but in this case I have a feeling that the Music classes are the core of your application... Don't build your core functionality in static classes, since you remove: testability, maintainability, reusability, extensibility, ...

You say:

I want to get rid of all my redundant code and make it easier to create new music sources.

Here again, inheritance is central...

In C#, whenever u use static classes forget about inheritance. The other way around, whenever u need inheritance, forget about static classes.

Why did you initially make them static anyway?

If you want to have only one instance available, make it a singleton. If not, just make it non-static!

  • The reason why I made it static was because I want to access the class from anywhere and everywhere without having to pass around the object to every constructor. Also, I only had a single source from the beginning so that's why inheritance was not obvious for me at the time I created the first class. – Christoffer Reijer Jul 18 '13 at 5:25
  • 1
    Thats why thinking about what u might need in the future is a good thing. "Do I want to support new sources in the future?". You say: "The reason why I made it static was because I want to access the class from anywhere and everywhere without having to pass around the object to every constructor" That is such a bad habit. It leads to extremely poor coding. In OOP u are supposed to pass around objects in this case. Static classes helps u to avoid this passing around, but breaks all the rest. Remove the statics, thats the first thing I advice u. PS:Statics can be good, but they're often misused. – Frederik P. Jul 18 '13 at 6:06
  • Well I do plan on moving the classes over to a plugin system which would make them objects with inheritance. But I still don't see the benefits of not using static in this case. Passing around objects seems a lot messier as I need to change constructor and line of code creating the object, whenever I want to give a new object access to the class. Combined with the fact that only a single instance would be needed of the class, it seems more logical to use a static class. OOP principles be damned if breaking them is the more pragmatic approach. – Christoffer Reijer Jul 18 '13 at 7:00
  • 1
    Have u read the link Baqueta provided in his answer: stackoverflow.com/questions/241339/… ? It has a great set f-of answers! Passing around objects and creating instances should NOT be an issue when developing .NET applications. That "way" of thinking conflicts with the OOP way of working. – Frederik P. Jul 18 '13 at 7:09
  • Yes, and only the point about testing caught my eye. The rest either don't apply or are avoidable with relative ease. But as I said, in this specific case it seems the best move is to move away from static classes and into a plugin system where each source is an instance of a plugin. But I'll still keep my static utility class. :) – Christoffer Reijer Jul 18 '13 at 7:22
1

I am not sure if someone is still interested in this topic but shorty i tried the following. Probably it is one way for a generic solution which involved some static behavior.

  public abstract class StructureItem {
        public int index = 0;
    }

    public abstract class StructureItem<T> : StructureItem where T : StructureItem
    {
        public static List<T> Elements = new List<T>();
    }

    public class TEST1 : StructureItem<TEST1>
    {
        public TEST1()
        {
            StructureItem a = this;
            this.index = 1;
            TEST1.Elements.Add(this);
        }
    }

    public class TEST2 : StructureItem<TEST2>
    {
        public TEST2()
        {
            StructureItem a = this;
            this.index = 2;
            TEST2.Elements.Add(this);
        }
    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            var test1 = new TEST1();
            var test2 = new TEST2();

            List<StructureItem> aList = new List<StructureItem>();

            aList.Add(test1);
            aList.Add(test2);

            Console.WriteLine("all Elements:");
            foreach (var item in aList)
            {
                Console.WriteLine("Element " + item.index);
            }
            Console.WriteLine("TEST1 Elements:");
            foreach (var item in TEST1.Elements)
            {
                Console.WriteLine("Element "+item.index);
            }
            Console.WriteLine("TEST2 Elements:");
            foreach (var item in TEST2.Elements)
            {
                Console.WriteLine("Element " + item.index);
            }

        }
    }

Output:

all Elements:
Element 1
Element 2
TEST1 Elements:
Element 1
TEST1 Elements:
Element 2

Not the answer you're looking for? Browse other questions tagged or ask your own question.