<p>I've been working with <a href="http://msdn.microsoft.com/en-us/library/aa479030.aspx" rel="noreferrer">providers</a> a fair bit lately, and I came across an interesting situation where I wanted to have an abstract class that had an abstract static method. I read a few posts on the topic, and it sort of made sense, but is there a nice clear explanation?</p>

[{'answer_id': 3291, 'author': 'David Wengier', 'author_id': 489, 'author_profile': 'https://Stackoverflow.com/users/489', 'pm_score': 6, 'selected': False, 'text': "<p>Static methods cannot be inherited or overridden, and that is why they can't be abstract. Since static methods are defined on the type, not the instance, of a class, they must be called explicitly on that type. So when you want to call a method on a child class, you need to use its name to call it. This makes inheritance irrelevant.</p>\n<p>Assume you could, for a moment, inherit static methods. Imagine this scenario:</p>\n<pre><code>public static class Base\n{\n    public static virtual int GetNumber() { return 5; }\n}\n\npublic static class Child1 : Base\n{\n    public static override int GetNumber() { return 1; }\n}\n\npublic static class Child2 : Base\n{\n    public static override int GetNumber() { return 2; }\n}\n</code></pre>\n<p>If you call Base.GetNumber(), which method would be called? Which value returned? It's pretty easy to see that without creating instances of objects, inheritance is rather hard. Abstract methods without inheritance are just methods that don't have a body, so can't be called.</p>\n"}, {'answer_id': 3292, 'author': 'Rytmis', 'author_id': 266, 'author_profile': 'https://Stackoverflow.com/users/266', 'pm_score': 3, 'selected': False, 'text': '<p>To add to the previous explanations, static method calls are bound to a specific method at <em>compile-time</em>, which rather rules out polymorphic behavior.</p>\n'}, {'answer_id': 3294, 'author': 'Lasse V. Karlsen', 'author_id': 267, 'author_profile': 'https://Stackoverflow.com/users/267', 'pm_score': 8, 'selected': True, 'text': "<p>Static methods are not <em>instantiated</em> as such, they're just available without an object reference.</p>\n\n<p>A call to a static method is done through the class name, not through an object reference, and the Intermediate Language (IL) code to call it will call the abstract method through the name of the class that defined it, not necessarily the name of the class you used.</p>\n\n<p>Let me show an example.</p>\n\n<p>With the following code:</p>\n\n<pre><code>public class A\n{\n    public static void Test()\n    {\n    }\n}\n\npublic class B : A\n{\n}\n</code></pre>\n\n<p>If you call B.Test, like this:</p>\n\n<pre><code>class Program\n{\n    static void Main(string[] args)\n    {\n        B.Test();\n    }\n}\n</code></pre>\n\n<p>Then the actual code inside the Main method is as follows:</p>\n\n<pre><code>.entrypoint\n.maxstack 8\nL0000: nop \nL0001: call void ConsoleApplication1.A::Test()\nL0006: nop \nL0007: ret \n</code></pre>\n\n<p>As you can see, the call is made to A.Test, because it was the A class that defined it, and not to B.Test, even though you can write the code that way.</p>\n\n<p>If you had <em>class types</em>, like in Delphi, where you can make a variable referring to a type and not an object, you would have more use for virtual and thus abstract static methods (and also constructors), but they aren't available and thus static calls are non-virtual in .NET.</p>\n\n<p>I realize that the IL designers could allow the code to be compiled to call B.Test, and resolve the call at runtime, but it still wouldn't be virtual, as you would still have to write some kind of class name there.</p>\n\n<p>Virtual methods, and thus abstract ones, are only useful when you're using a variable which, at runtime, can contain many different types of objects, and you thus want to call the right method for the current object you have in the variable. With static methods you need to go through a class name anyway, so the exact method to call is known at compile time because it can't and won't change.</p>\n\n<p>Thus, virtual/abstract static methods are not available in .NET.</p>\n"}, {'answer_id': 6674, 'author': 'Chris Hanson', 'author_id': 714, 'author_profile': 'https://Stackoverflow.com/users/714', 'pm_score': 4, 'selected': False, 'text': '<p>Another respondent (McDowell) said that polymorphism only works for object instances.  That should be qualified; there are languages that do treat classes as instances of a "Class" or "Metaclass" type.  These languages do support polymorphism for both instance and class (static) methods.</p>\n\n<p>C#, like Java and C++ before it, is not such a language; the <code>static</code> keyword is used explicitly to denote that the method is statically-bound rather than dynamic/virtual.</p>\n'}, {'answer_id': 15090, 'author': 'Fabio Gomes', 'author_id': 727, 'author_profile': 'https://Stackoverflow.com/users/727', 'pm_score': 3, 'selected': False, 'text': "<p>We actually override static methods (in delphi), it's a bit ugly, but it works just fine for our needs.</p>\n\n<p>We use it so the classes can have a list of their available objects without the class instance, for example, we have a method that looks like this:</p>\n\n<pre><code>class function AvailableObjects: string; override;\nbegin\n  Result := 'Object1, Object2';\nend; \n</code></pre>\n\n<p>It's ugly but necessary, this way we can instantiate just what is needed, instead of having all the classes instantianted just to search for the available objects.</p>\n\n<p>This was a simple example, but the application itself is a client-server application which has all the classes available in just one server, and multiple different clients which might not need everything the server has and will never need an object instance.</p>\n\n<p>So this is much easier to maintain than having one different server application for each client.</p>\n\n<p>Hope the example was clear.</p>\n"}, {'answer_id': 862763, 'author': 'AMing', 'author_id': 76538, 'author_profile': 'https://Stackoverflow.com/users/76538', 'pm_score': 1, 'selected': False, 'text': '<p>The abstract methods are implicitly virtual. Abstract methods require an instance, but static methods do not have an instance. So, you can have a static method in an abstract class, it just cannot be static abstract (or abstract static).</p>\n'}, {'answer_id': 2286540, 'author': 'user275801', 'author_id': 275801, 'author_profile': 'https://Stackoverflow.com/users/275801', 'pm_score': 4, 'selected': False, 'text': '<p>Here is a situation where there is definitely a need for inheritance for static fields and methods:</p>\n\n<pre><code>abstract class Animal\n{\n  protected static string[] legs;\n\n  static Animal() {\n    legs=new string[0];\n  }\n\n  public static void printLegs()\n  {\n    foreach (string leg in legs) {\n      print(leg);\n    }\n  }\n}\n\n\nclass Human: Animal\n{\n  static Human() {\n    legs=new string[] {"left leg", "right leg"};\n  }\n}\n\n\nclass Dog: Animal\n{\n  static Dog() {\n    legs=new string[] {"left foreleg", "right foreleg", "left hindleg", "right hindleg"};\n  }\n}\n\n\npublic static void main() {\n  Dog.printLegs();\n  Human.printLegs();\n}\n\n\n//what is the output?\n//does each subclass get its own copy of the array "legs"?\n</code></pre>\n'}, {'answer_id': 66070907, 'author': 'Burakumin', 'author_id': 6053778, 'author_profile': 'https://Stackoverflow.com/users/6053778', 'pm_score': 3, 'selected': False, 'text': '<p>This question is 12 years old but it still needs to be given a better answer. As few noted in the comments and contrarily to what all answers pretend it would certainly make sense to have static abstract methods in C#. As philosopher Daniel Dennett put it, a failure of imagination is not an insight into necessity. There is a common mistake in not realizing that C# is not only an OOP language. A pure OOP perspective on a given concept leads to a restricted and in the current case misguided examination. Polymorphism is not only about subtying polymorphism: it also includes parametric polymorphism (aka generic programming) and C# has been supporting this for a long time now. Within this additional paradigm, abstract classes (and most types) are not only used to provide a type to instances. They can also be used as <strong>bounds for generic parameters</strong>; something that has been understood by users of certain languages (like for example Haskell, but also more recently Scala, Rust or Swift) for years.</p>\n<p>In this context you may want to do something like this:</p>\n<pre class="lang-cs prettyprint-override"><code>void Catch&lt;TAnimal&gt;() where TAnimal : Animal\n{\n    string scientificName = TAnimal.ScientificName; // abstract static property\n    Console.WriteLine($&quot;Let\'s catch some {scientificName}&quot;);\n    …\n}\n</code></pre>\n<p>And here the capacity to express static members that can be specialized by subclasses <strong>totally makes sense</strong>!</p>\n<p>Unfortunately C# does not allow abstract static members but I\'d like to propose a pattern that can <strong>emulate</strong> them reasonably well. This pattern is not perfect (it imposes some restrictions on inheritance) but as far as I can tell it is typesafe.</p>\n<p>The main idea is to associate an abstract companion class (here <code>SpeciesFor&lt;TAnimal&gt;</code>) to the one that should contain static abstract members (here <code>Animal</code>):</p>\n<pre class="lang-cs prettyprint-override"><code>public abstract class SpeciesFor&lt;TAnimal&gt; where TAnimal : Animal\n{\n    public static SpeciesFor&lt;TAnimal&gt; Instance { get { … } }\n\n    // abstract &quot;static&quot; members\n\n    public abstract string ScientificName { get; }\n    \n    …\n}\n\npublic abstract class Animal { … }\n</code></pre>\n<p>Now we would like to make this work:</p>\n<pre class="lang-cs prettyprint-override"><code>void Catch&lt;TAnimal&gt;() where TAnimal : Animal\n{\n    string scientificName = SpeciesFor&lt;TAnimal&gt;.Instance.ScientificName;\n    Console.WriteLine($&quot;Let\'s catch some {scientificName}&quot;);\n    …\n}\n</code></pre>\n<p>Of course we have two problems to solve:</p>\n<ol>\n<li>How do we make sure an implementer of a subclass of <code>Animal</code> provides a specific instance of <code>SpeciesFor&lt;TAnimal&gt;</code> to this subclass?</li>\n<li>How does the property <code>SpeciesFor&lt;TAnimal&gt;.Instance</code> retrieve this information?</li>\n</ol>\n<p>Here is how we can solve 1:</p>\n<pre class="lang-cs prettyprint-override"><code>public abstract class Animal&lt;TSelf&gt; where TSelf : Animal&lt;TSelf&gt;\n{\n    private Animal(…) {}\n    \n    public abstract class OfSpecies&lt;TSpecies&gt; : Animal&lt;TSelf&gt;\n        where TSpecies : SpeciesFor&lt;TSelf&gt;, new()\n    {\n        protected OfSpecies(…) : base(…) { }\n    }\n    \n    …\n}\n</code></pre>\n<p>By making the constructor of <code>Animal&lt;TSelf&gt;</code> private we make sure that all its subclasses are also subclasses of inner class <code>Animal&lt;TSelf&gt;.OfSpecies&lt;TSpecies&gt;</code>. So these subclasses must specify a <code>TSpecies</code> type that has a <code>new()</code> bound.</p>\n<p>For 2 we can provide the following implementation:</p>\n<pre class="lang-cs prettyprint-override"><code>public abstract class SpeciesFor&lt;TAnimal&gt; where TAnimal : Animal&lt;TAnimal&gt;\n{\n    private static SpeciesFor&lt;TAnimal&gt; _instance;\n\n    public static SpeciesFor&lt;TAnimal&gt; Instance =&gt; _instance ??= MakeInstance();\n\n    private static SpeciesFor&lt;TAnimal&gt; MakeInstance()\n    {\n        Type t = typeof(TAnimal);\n        while (true)\n        {\n            if (t.IsConstructedGenericType\n                    &amp;&amp; t.GetGenericTypeDefinition() == typeof(Animal&lt;&gt;.OfSpecies&lt;&gt;))\n                return (SpeciesFor&lt;TAnimal&gt;)Activator.CreateInstance(t.GenericTypeArguments[1]);\n            t = t.BaseType;\n            if (t == null)\n                throw new InvalidProgramException();\n        }\n    }\n\n    // abstract &quot;static&quot; members\n\n    public abstract string ScientificName { get; }\n    \n    …\n}\n</code></pre>\n<p>How do we know that the reflection code inside <code>MakeInstance()</code> never throws? As we\'ve already said, almost all classes within the hierarchy of <code>Animal&lt;TSelf&gt;</code> are also subclasses of <code>Animal&lt;TSelf&gt;.OfSpecies&lt;TSpecies&gt;</code>. So we know that for these classes a specific <code>TSpecies</code> must be provided. This type is also necessarily constructible thanks to constraint <code>: new()</code>. But this still leaves out abstract types like <code>Animal&lt;Something&gt;</code> that have no associated species. Now we can convince ourself that the <a href="https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern" rel="nofollow noreferrer">curiously recurring template pattern</a> <code>where TAnimal : Animal&lt;TAnimal&gt;</code> makes it impossible to write <code>SpeciesFor&lt;Animal&lt;Something&gt;&gt;.Instance</code> as type <code>Animal&lt;Something&gt;</code> is never a subtype of <code>Animal&lt;Animal&lt;Something&gt;&gt;</code>.</p>\n<p>Et voilà:</p>\n<pre class="lang-cs prettyprint-override"><code>public class CatSpecies : SpeciesFor&lt;Cat&gt;\n{\n    // overriden &quot;static&quot; members\n\n    public override string ScientificName =&gt; &quot;Felis catus&quot;;\n    public override Cat CreateInVivoFromDnaTrappedInAmber() { … }\n    public override Cat Clone(Cat a) { … }\n    public override Cat Breed(Cat a1, Cat a2) { … }\n}\n\npublic class Cat : Animal&lt;Cat&gt;.OfSpecies&lt;CatSpecies&gt;\n{\n    // overriden members\n\n    public override string CuteName { get { … } }\n}\n\npublic class DogSpecies : SpeciesFor&lt;Dog&gt;\n{\n    // overriden &quot;static&quot; members\n\n    public override string ScientificName =&gt; &quot;Canis lupus familiaris&quot;;\n    public override Dog CreateInVivoFromDnaTrappedInAmber() { … }\n    public override Dog Clone(Dog a) { … }\n    public override Dog Breed(Dog a1, Dog a2) { … }\n}\n\npublic class Dog : Animal&lt;Dog&gt;.OfSpecies&lt;DogSpecies&gt;\n{\n    // overriden members\n\n    public override string CuteName { get { … } }\n}\n\npublic class Program\n{\n    public static void Main()\n    {\n        ConductCrazyScientificExperimentsWith&lt;Cat&gt;();\n        ConductCrazyScientificExperimentsWith&lt;Dog&gt;();\n        ConductCrazyScientificExperimentsWith&lt;Tyranosaurus&gt;();\n        ConductCrazyScientificExperimentsWith&lt;Wyvern&gt;();\n    }\n    \n    public static void ConductCrazyScientificExperimentsWith&lt;TAnimal&gt;()\n        where TAnimal : Animal&lt;TAnimal&gt;\n    {\n        // Look Ma! No animal instance polymorphism!\n        \n        TAnimal a2039 = SpeciesFor&lt;TAnimal&gt;.Instance.CreateInVivoFromDnaTrappedInAmber();\n        TAnimal a2988 = SpeciesFor&lt;TAnimal&gt;.Instance.CreateInVivoFromDnaTrappedInAmber();\n        TAnimal a0400 = SpeciesFor&lt;TAnimal&gt;.Instance.Clone(a2988);\n        TAnimal a9477 = SpeciesFor&lt;TAnimal&gt;.Instance.Breed(a0400, a2039);\n        TAnimal a9404 = SpeciesFor&lt;TAnimal&gt;.Instance.Breed(a2988, a9477);\n        \n        Console.WriteLine(\n            &quot;The confederation of mad scientists is happy to announce the birth &quot; +\n            $&quot;of {a9404.CuteName}, our new {SpeciesFor&lt;TAnimal&gt;.Instance.ScientificName}.&quot;);\n    }\n}\n</code></pre>\n<p>A limitation of this pattern is that it is not possible (as far as I can tell) to extend the class hierarchy in a satifying manner. For example we cannot introduce an intermediary <code>Mammal</code> class associated to a <code>MammalClass</code> companion. Another is that it does not work for static members in interfaces which would be more flexible than abstract classes.</p>\n'}, {'answer_id': 69666855, 'author': '0BLU', 'author_id': 3338196, 'author_profile': 'https://Stackoverflow.com/users/3338196', 'pm_score': 4, 'selected': False, 'text': '<p>With <code>.NET 6</code> / <code>C# 10/next/preview</code> you are able to do exactly that with &quot;Static abstract members in interfaces&quot;.</p>\n<p>(At the time of writing the code compiles successfully but some IDEs have problems highlighting the code)</p>\n<p><a href="https://sharplab.io/#v2:EYLgZgpghgLgrgJwgZwLQGUawJYGMCCwyMCUuMAshALbAQLICSAdizPWGSgDQwjYAbAD4ABAEwBGALAAoWcyjUUABy4ACTDgJESZGABUUMbMwDmsgN6y1NtSIDMak+wSdcENY3QB7JYWKk5GwcXNa2VjK2UXaOUDqBMHYSAGxJAAxqAMJQAgJUABQAlADcYTYAvrJlMXZiahQAnpkCUMjI+Gognj5+8XrBrqGR4dVRIinp3b4Q/rpBzC5uEAB02bkFhaMjw9HRIgDsagBEAJrecGq4OQIQACZZLW34R6U70ZVvH9UOtfVNj8gAEKdKa9AL9BYhdzVCK7GzjVLjDJeaazBIDJara4bLY2WFwsaHU7nS7XO4PVpAl64tQfKJfN4/cRJfYwqpvMaOBF2AAs9SgJnySIA2gBdNRQBCmZCbDnbAlRACqyAgmmMuGalKoMAAFt5bgAeRqap4APiKrwVtmVqqw6pNyG1esNxoBgPNJRpDIJTImIj5NrVeAdTv1Bv0HrUAHcdfQPPoQSiwXMYBihgT8VbxgBOfIAEiOFhgDWUEG8YHy+kKywAcooIOUsesIEU1EhkHABHw1BZ9E28i3CuUjp65RV2T6uX6AyqgxqAaHbuhsNRlDdw5GY3G1AmukmZn15ot03DMwqAPQAKjUqDUABlvN4ANYSxK6jyMO+XfUrNQABSQGBizUZABBXZY1AAKTgYhv2YcETDuGkok/AB9NIMLSLpcG8eDdEQ24IIAQiI/RkNsNDMOSbDrkmOc0T0QxiBMUxln3BijyhCAQBANYByKcibEojDQFJXJeTUYVxlWXDkG8G5RWkzJZPk7iQAAdQQbB2DvRChQkNJZStIS73QtIDK6QDBJsS9z2snNK37DZRwJOlbA+cogA=" rel="noreferrer">SharpLab Demo</a></p>\n<pre class="lang-cs prettyprint-override"><code>using System;\n\nnamespace StaticAbstractTesting\n{\n    public interface ISomeAbstractInterface\n    {\n        public abstract static string CallMe();\n    }\n\n    public class MyClassA : ISomeAbstractInterface\n    {\n        static string ISomeAbstractInterface.CallMe()\n        {\n            return &quot;You called ClassA&quot;;\n        }\n    }\n\n    public class MyClassB : ISomeAbstractInterface\n    {\n        static string ISomeAbstractInterface.CallMe()\n        {\n            return &quot;You called ClassB&quot;;\n        }\n    }\n\n    public class Program\n    {\n\n        public static void Main(string[] args)\n        {\n            UseStaticClassMethod&lt;MyClassA&gt;();\n            UseStaticClassMethod&lt;MyClassB&gt;();\n        }\n\n        public static void UseStaticClassMethod&lt;T&gt;() where T : ISomeAbstractInterface\n        {\n            Console.WriteLine($&quot;{typeof(T).Name}.CallMe() result: {T.CallMe()}&quot;);\n        }\n    }\n}\n\n</code></pre>\n<p>Since this is a major change in the runtime, the resulting IL code also looks really clean, which means that this is not just syntactic sugar.</p>\n<pre><code>public static void UseStaticClassMethodSimple&lt;T&gt;() where T : ISomeAbstractInterface {\nIL_0000: constrained. !!T\nIL_0006: call string StaticAbstractTesting.ISomeAbstractInterface::CallMe()\nIL_000b: call void [System.Console]System.Console::WriteLine(string)\nIL_0010: ret\n}\n</code></pre>\n<p>Resources:</p>\n<ul>\n<li><a href="https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/static-abstract-interface-methods" rel="noreferrer">https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/static-abstract-interface-methods</a></li>\n<li><a href="https://github.com/dotnet/csharplang/issues/4436" rel="noreferrer">https://github.com/dotnet/csharplang/issues/4436</a></li>\n</ul>\n'}, {'answer_id': 70454809, 'author': 'Geniusbaby', 'author_id': 17743713, 'author_profile': 'https://Stackoverflow.com/users/17743713', 'pm_score': 1, 'selected': False, 'text': "<p>It's available in C# 10 as a preview feature for now.</p>\n"}]
['https://Stackoverflow.com/questions/3284', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/493/']