246

I have several classes that do not really need any state. From the organizational point of view, I would like to put them into hierarchy.

But it seems I can't declare inheritance for static classes.

Something like that:

public static class Base
{
}

public static class Inherited : Base
{
}

will not work.

Why have the designers of the language closed that possibility?

Eoin Campbell
  • 43,500
  • 17
  • 101
  • 157
User
  • 30,403
  • 22
  • 79
  • 107
  • Possible duplicate of [How can a static class derive from an object?](http://stackoverflow.com/questions/556203/how-can-a-static-class-derive-from-an-object) – Moslem Ben Dhaou Nov 26 '15 at 13:48

13 Answers13

189

Citation from here:

This is actually by design. There seems to be no good reason to inherit a static class. It has public static members that you can always access via the class name itself. The only reasons I have seen for inheriting static stuff have been bad ones, such as saving a couple of characters of typing.

There may be reason to consider mechanisms to bring static members directly into scope (and we will in fact consider this after the Orcas product cycle), but static class inheritance is not the way to go: It is the wrong mechanism to use, and works only for static members that happen to reside in a static class.

(Mads Torgersen, C# Language PM)

Other opinions from channel9

Inheritance in .NET works only on instance base. Static methods are defined on the type level not on the instance level. That is why overriding doesn't work with static methods/properties/events...

Static methods are only held once in memory. There is no virtual table etc. that is created for them.

If you invoke an instance method in .NET, you always give it the current instance. This is hidden by the .NET runtime, but it happens. Each instance method has as first argument a pointer (reference) to the object that the method is run on. This doesn't happen with static methods (as they are defined on type level). How should the compiler decide to select the method to invoke?

(littleguru)

And as a valuable idea, littleguru has a partial "workaround" for this issue: the Singleton pattern.

stomy
  • 1,778
  • 1
  • 15
  • 16
boj
  • 10,935
  • 5
  • 38
  • 57
  • 1
    As to your first citation, you can cast an instance class as the base class and then use its public members. – Anthony D May 15 '09 at 13:13
  • 110
    Lack of imagination on Torgersen's side, really. I had a pretty good reason for wanting to do this :) – Thorarin Jan 19 '10 at 14:31
  • 14
    How about this? You have a dll that isn't open source / you don't have access to it's source, let's say NUnit. You want to extend it's Assert class to have a method like Throws<>(Action a) (yes, that's there too, but at one point it wasn't.) You could add to your project a Assert:NUnit.Framework.Assert class, and then add a Throws method. Problem solved. It's cleaner to use in the code too... instead of having to come up with another classname and remember that classname, just type Assert. and see the available methods. – user420667 Nov 11 '11 at 20:42
  • @user420667 this could be adressed with extension methods for static classes. No need for inheritance. – Konrad Morawski Jul 31 '13 at 12:09
  • 4
    @KonradMorawski It's impossible to write extension methods for static classes. http://stackoverflow.com/questions/249222/can-i-add-extension-methods-to-an-existing-static-class – Martin Braun Jul 16 '14 at 10:19
  • 2
    @modiX Of course. You misunderstood me here. What I meant is that the functionality required in the scenario described by user420667 could be provided (**in future**) by as little as allowing extension methods for static classes. No static inheritance necessary. That's why his scenario didn't strike me as a very good rationale for introducing static inheritance. If C# was to be modified in this aspect, why go for a major redesign when a minor one would be just as good in practice. – Konrad Morawski Jul 17 '14 at 18:58
  • @boj: Sorry I downvote your answer, because static class can inherit from objects. You didn't mention that. Can you mention that as well as a code as to how to inherit from objects? It shows in visual studio mate. – Jasmine Apr 01 '15 at 00:35
  • 6
    @Learner That's not really fair. In .Net **everything** inherits from `object`, and everyone is expected to know that. So static classes **always** inherit from `object`, whether you specify it explicitly or not. – RenniePet Feb 07 '18 at 09:10
  • To the "everything is object" thread: https://stackoverflow.com/questions/436211/is-everything-in-net-an-object – boj Sep 11 '21 at 21:26
76

The main reason that you cannot inherit a static class is that they are abstract and sealed (this also prevents any instance of them from being created).

So this:

static class Foo { }

compiles to this IL:

.class private abstract auto ansi sealed beforefieldinit Foo
  extends [mscorlib]System.Object
 {
 }
Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
  • 24
    You are saying that static was implemented as abstract + sealed. He wants to know *why* this was done. Why is it sealed? – Lucas Apr 22 '09 at 19:34
  • 27
    This doesn't answer the question it all; it just restates the issue he was asking about. – Igby Largeman Mar 22 '10 at 19:22
  • 29
    Well, the OP should have asked "Why are static classes sealed", not "Why can't I inherit from static classes?", the answer to which is of course *"because they're sealed"*. This answer gets my vote. – Alex Budovski May 10 '10 at 03:41
  • 6
    thanks for sharing that static classes get automatically compiled as sealed classes - I was wondering how/when that happened! – Mark Sep 21 '11 at 19:54
  • 34
    @AlexBudovski: This answer is correct but as useless as a telling a lost person "you are in front of me" when they ask you "where am I". – DeepSpace101 Feb 28 '14 at 22:37
  • @Andrew ,At the same time abstract sealed class cannot be created in c# .So why there is such contradiction .Not able to find good explanation yet .Read this, http://stackoverflow.com/questions/19404589/abstract-class-cannot-be-sealed-in-c – KumarHarsh Dec 18 '14 at 05:00
  • This is the issue, Not the answer – Mohammad Nikravesh Mar 13 '19 at 09:16
  • @MohammadNikravesh This is the answer may not be the correct or complete answer but at least an answer – Trikaldarshiii Jan 10 '21 at 21:08
  • 1
    Guys, stating the kind of lock on a door does not answer the question of what the rationale is behind locking the door. The end of the question refers to the designers of the language not the implementers, further reinforcing the idea that he is asking why the decision was made, not how it was implemented. The how is of course informative as well, and fully appropriate if the why question is also answered. – Arlen Beiler Mar 10 '21 at 22:23
25

Think about it this way: you access static members via type name, like this:

MyStaticType.MyStaticMember();

Were you to inherit from that class, you would have to access it via the new type name:

MyNewType.MyStaticMember();

Thus, the new item bears no relationships to the original when used in code. There would be no way to take advantage of any inheritance relationship for things like polymorphism.

Perhaps you're thinking you just want to extend some of the items in the original class. In that case, there's nothing preventing you from just using a member of the original in an entirely new type.

Perhaps you want to add methods to an existing static type. You can do that already via extension methods.

Perhaps you want to be able to pass a static Type to a function at runtime and call a method on that type, without knowing exactly what the method does. In that case, you can use an Interface.

So, in the end you don't really gain anything from inheriting static classes.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • 5
    You cannot add methods to an existing static type via an extension method. Please see my comment on the accepted answer for an example desired use. (Basically you would want to just rename what you've named MyNewType as MyStaticType, so MyStaticType: OldProject.MyStaticType) – user420667 Nov 11 '11 at 21:15
  • 2
    One could define inheritance relations with static types and virtual static members in such a way that a `SomeClass where T:Foo` could access members of `Foo`, and if `T` was a class which overrode some virtual static members of `Foo`, the generic class would use those overrides. It would probably even be possible to define a convention via which languages could do so in a fashion compatible with the current CLR (e.g. a class with such members should define a protected non-static class which contains such instance members, along with a static field holding an instance of that type). – supercat Nov 29 '12 at 21:51
  • I found myself with a case where I believe inheriting a static class is the right thing to do, although obviously you can access them anyway. I have a static class for sending raw data streams to the printer (for talking to industrial label printers). It has a bunch of windows API declarations. I now find myself writing another class for messing with printers which needs the same API calls. Combine? Not good. Declare them twice? Ugly. Inherit? Good, but not permitted. – Loren Pechtel May 09 '20 at 20:37
3

You can use composition instead... this will allow you to access class objects from the static type. But still cant implements interfaces or abstract classes

3

Hmmm... would it be much different if you just had non-static classes filled with static methods..?

CookieOfFortune
  • 13,836
  • 8
  • 42
  • 58
  • 3
    That's what is left to me. I do it this way. And I don't like it. – User Apr 21 '09 at 19:42
  • I've done it this way as well, but for some reason it doesn't feel aesthetic when you know you will never instantiate the object. I always agonize about details like this, despite the fact that there is no material cost of it. – gdbj Feb 08 '15 at 18:51
  • In non-static class filled with static methods you cannot put extension methods :) – Jakub Szułakiewicz Oct 01 '19 at 13:13
3

What you want to achieve by using class hierarchy can be achieved merely through namespacing. So languages that support namespapces ( like C#) will have no use of implementing class hierarchy of static classes. Since you can not instantiate any of the classes, all you need is a hierarchical organization of class definitions which you can obtain through the use of namespaces

Amit
  • 805
  • 1
  • 8
  • 11
  • I have a generic loader that receives a class as type. That class has 5 helper methods and 2 methods that return a string (name and description). I might have picked it wrong (I think so), but the only solution I found was to instantiate the class in the generic loader, to access the methods... meh. – ANeves Nov 22 '10 at 18:39
  • The alternative would be a giant dictionary, I guess. Also, when you say "what you want to achieve" you should instead say "what you seem to be aiming for" or something similar. – ANeves Nov 22 '10 at 18:40
2

A workaround you can do is not use static classes but hide the constructor so the classes static members are the only thing accessible outside the class. The result is an inheritable "static" class essentially:

public class TestClass<T>
{
    protected TestClass()
    { }

    public static T Add(T x, T y)
    {
        return (dynamic)x + (dynamic)y;
    }
}

public class TestClass : TestClass<double>
{
    // Inherited classes will also need to have protected constructors to prevent people from creating instances of them.
    protected TestClass()
    { }
}

TestClass.Add(3.0, 4.0)
TestClass<int>.Add(3, 4)

// Creating a class instance is not allowed because the constructors are inaccessible.
// new TestClass();
// new TestClass<int>();

Unfortunately because of the "by-design" language limitation we can't do:

public static class TestClass<T>
{
    public static T Add(T x, T y)
    {
        return (dynamic)x + (dynamic)y;
    }
}

public static class TestClass : TestClass<double>
{
}
FocusedWolf
  • 1,062
  • 16
  • 19
2

Although you can access "inherited" static members through the inherited classes name, static members are not really inherited. This is in part why they can't be virtual or abstract and can't be overridden. In your example, if you declared a Base.Method(), the compiler will map a call to Inherited.Method() back to Base.Method() anyway. You might as well call Base.Method() explicitly. You can write a small test and see the result with Reflector.

So... if you can't inherit static members, and if static classes can contain only static members, what good would inheriting a static class do?

Lucas
  • 17,277
  • 5
  • 45
  • 40
1

You can do something that will look like static inheritance.

Here is the trick:

public abstract class StaticBase<TSuccessor>
    where TSuccessor : StaticBase<TSuccessor>, new()
{
    protected static readonly TSuccessor Instance = new TSuccessor();
}

Then you can do this:

public class Base : StaticBase<Base>
{
    public Base()
    {
    }

    public void MethodA()
    {
    }
}

public class Inherited : Base
{
    private Inherited()
    {
    }

    public new static void MethodA()
    {
        Instance.MethodA();
    }
}

The Inherited class is not static itself, but we don't allow to create it. It actually has inherited static constructor which builds Base, and all properties and methods of Base available as static. Now the only thing left to do make static wrappers for each method and property you need to expose to your static context.

There are downsides like the need for manual creation of static wrapper methods and new keyword. But this approach helps support something that is really similar to static inheritance.

P.S. We used this for creating compiled queries, and this actually can be replaced with ConcurrentDictionary, but a static read-only field with its thread safety was good enough.

Kindle Q
  • 944
  • 2
  • 19
  • 28
Konard
  • 2,298
  • 28
  • 21
1

My answer: poor design choice. ;-)

This is an interesting debate focused on syntax impact. The core of the argument, in my view, is that a design decision led to sealed static classes. A focus on transparency of the static class's names appearing at the top level instead of hiding ('confusing') behind child names? One can image a language implementation that could access the base or the child directly, confusing.

A pseudo example, assuming static inheritance was defined in some way.

public static class MyStaticBase
{
    SomeType AttributeBase;
}

public static class MyStaticChild : MyStaticBase
{
    SomeType AttributeChild;
}

would lead to:

 // ...
 DoSomethingTo(MyStaticBase.AttributeBase);
// ...

which could (would?) impact the same storage as

// ...
DoSomethingTo(MyStaticChild.AttributeBase);
// ...

Very confusing!

But wait! How would the compiler deal with MyStaticBase and MyStaticChild having the same signature defined in both? If the child overrides than my above example would NOT change the same storage, maybe? This leads to even more confusion.

I believe there is a strong informational space justification for limited static inheritance. More on the limits shortly. This pseudocode shows the value:

public static class MyStaticBase<T>
{
   public static T Payload;
   public static void Load(StorageSpecs);
   public static void Save(StorageSpecs);
   public static SomeType AttributeBase
   public static SomeType MethodBase(){/*...*/};
}

Then you get:

public static class MyStaticChild : MyStaticBase<MyChildPlayloadType>
{
   public static SomeType AttributeChild;
   public static SomeType SomeChildMethod(){/*...*/};
   // No need to create the PlayLoad, Load(), and Save().
   // You, 'should' be prevented from creating them, more on this in a sec...
} 

Usage looks like:

// ...
MyStaticChild.Load(FileNamePath);
MyStaticChild.Save(FileNamePath);
doSomeThing(MyStaticChild.Payload.Attribute);
doSomething(MyStaticChild.AttributeBase);
doSomeThing(MyStaticChild.AttributeChild);
// ...

The person creating the static child does not need to think about the serialization process as long as they understand any limitations that might be placed on the platform's or environment's serialization engine.

Statics (singletons and other forms of 'globals') often come up around configuration storage. Static inheritance would allow this sort of responsibility allocation to be cleanly represented in the syntax to match a hierarchy of configurations. Though, as I showed, there is plenty of potential for massive ambiguity if basic static inheritance concepts are implemented.

I believe the right design choice would be to allow static inheritance with specific limitations:

  1. No override of anything. The child cannot replace the base attributes, fields, or methods,... Overloading should be ok, as long as there is a difference in signature allowing the compiler to sort out child vs base.
  2. Only allow generic static bases, you cannot inherit from a non-generic static base.

You could still change the same store via a generic reference MyStaticBase<ChildPayload>.SomeBaseField. But you would be discouraged since the generic type would have to be specified. While the child reference would be cleaner: MyStaticChild.SomeBaseField.

I am not a compiler writer so I am not sure if I am missing something about the difficulties of implementing these limitations in a compiler. That said, I am a strong believer that there is an informational space need for limited static inheritance and the basic answer is that you can't because of a poor (or over simple) design choice.

0

When we create a static class that contains only the static members and a private constructor.The only reason is that the static constructor prevent the class from being instantiated for that we can not inherit a static class .The only way to access the member of the static class by using the class name itself.Try to inherit a static class is not a good idea.

0

Static classes and class members are used to create data and functions that can be accessed without creating an instance of the class. Static class members can be used to separate data and behavior that is independent of any object identity: the data and functions do not change regardless of what happens to the object. Static classes can be used when there is no data or behavior in the class that depends on object identity.

A class can be declared static, which indicates that it contains only static members. It is not possible to use the new keyword to create instances of a static class. Static classes are loaded automatically by the .NET Framework common language runtime (CLR) when the program or namespace that contains the class is loaded.

Use a static class to contain methods that are not associated with a particular object. For example, it is a common requirement to create a set of methods that do not act on instance data and are not associated to a specific object in your code. You could use a static class to hold those methods.

Following are the main features of a static class:

  1. They only contain static members.

  2. They cannot be instantiated.

  3. They are sealed.

  4. They cannot contain Instance Constructors (C# Programming Guide).

Creating a static class is therefore basically the same as creating a class that contains only static members and a private constructor. A private constructor prevents the class from being instantiated.

The advantage of using a static class is that the compiler can check to make sure that no instance members are accidentally added. The compiler will guarantee that instances of this class cannot be created.

Static classes are sealed and therefore cannot be inherited. They cannot inherit from any class except Object. Static classes cannot contain an instance constructor; however, they can have a static constructor. For more information, see Static Constructors (C# Programming Guide).

Zone
  • 9
  • 1
0

I run into the problem when trying to code an IComparer<T> implementation against a third-party library where T is an enum embedded in a class as in the following:

public class TheClass
{
    public enum EnumOfInterest
    {
    }
}

But because the enum is defined within a third-party library class, I can't write the comparer because the following gives a "cannot extends list" error:

public class MyComparer : IComparer<TheClass.EnumOfInterest>
{
}

I'm not even extending a static class -- I'm just implementing a comparer of a enum defined in a class.