C# Static Member "Inheritance" - Why Does This Exist at All

C# static member inheritance - why does this exist at all?

So, the "inheritance" of static
members merely looks like namespace
pollution

That's right, except that one guy's pollution is another guy's added spicy flavouring.

I think Martin Fowler, in his work on DSLs, has suggested using inheritance in this way to allow convenient access to static methods, allowing those methods to be used without class name qualification. So the calling code has to be in a class that inherits the class in which the methods are defined. (I think it's a rotten idea.)

In my opinion, static members should not be mixed into a class with a non-static purpose, and the issue you raise here is part of the reason why it's important not to mix them.

Hiding private static mutable data inside the implementation of an otherwise "instancey" class is particularly horrible. But then there are static methods, which are even worse mixers. Here's a typical use of static methods mixed into a class:

public class Thing
{
// typical per-instance stuff
int _member1;
protected virtual void Foo() { ... }
public void Bar() { ... }

// factory method
public static Thing Make()
{
return new Thing();
}
}

It's the static factory method pattern. It's pointless most of the time, but even worse is that now we have this:

public class AnotherThing : Thing { }

This now has a static Make method which returns a Thing, not a AnotherThing.

This kind of mismatch strongly implies that anything with static methods should be sealed. Static members fail to integrate well with inheritance. It makes no sense to have them heritable. So I keep static things in separate static classes, and I gripe about redundantly having to declare every member static when I've already said that the class is static.

But it's just one of those too-late-now things. All real, working languages (and libraries, and products) have a few of them. C# has remarkably few.

C# Inheriting Static Methods?

A work-around might be to declare a property of type Action in the base abstract class, that holds the method to be called. Then initialize this property during derived classes instantiation, by calling base class constructor:

abstract class DoSomething
{
public Action DoWhateverItIsThatIDo { get; set; }

protected DoSomething() { DoWhateverItIsThatIDo = DoSomething.DoIt; }

protected DoSomething(Action whatAction)
{
DoWhateverItIsThatIDo = whatAction;
}

protected static void DoIt()
{
Console.WriteLine("You asked the abstract class to work. Too bad.");
}
}

class InspireMe : DoSomething
{
public InspireMe() : base(InspireMe.DoIt) { }

private static void DoIt()
{
Console.WriteLine("You are amazing.");
}
}

class InsultMe : DoSomething
{
public InsultMe() : base(InsultMe.DoIt) { }

private static void DoIt()
{
Console.WriteLine("You aren't worth it.");
}
}

class DoWhatBaseClassDoes : DoSomething
{
public DoWhatBaseClassDoes() : base() {}
}

class Program
{
static void Main(string[] args)
{
DoSomething worker = new InsultMe();
worker.DoWhateverItIsThatIDo();

worker = new InspireMe();
worker.DoWhateverItIsThatIDo();

// In this case base class method is invoked
worker = new DoWhatBaseClassDoes();
worker.DoWhateverItIsThatIDo();
}
}

Making a superclass have a static variable that's different for each subclass in c#

While this works fine, I'm wondering if there's a more elegant or built-in way of doing this?

There isn't really a built-in way of doing this, as you're kind of violating basic OO principles here. Your base class should have no knowledge of subclasses in traditional object oriented theory.

That being said, if you must do this, your implementation is probably about as good as you're going to get, unless you can add some other info to the subclasses directly. If you need to control this, and you can't change subclasses, this will probably be your best approach.

Why is this static instance of the parent shared between new instances of children?

You should become more familiar with static keyword. This article could be helpful.

Fields or properties marked static are belongs to class itself but not to instances of this class. When you create new instance of Dog the field _name initializes with "Dog" string. But when you creates new instance of Cat the field _name changes its value for "Cat" string.

As _name belongs to base Animal class, every instance of descendant class will be referenced to the same value.

You should remove the static modifier, if you want to make _name belongs to instances of classes and not to class itself.

C# Same variables, static and not, on every derived class

Is there a reason that you need sides to be static? For example, do you need to know the number of sides for a shape without having an instance?

If so, I can't see any reason for inheritance, just do Circle.sides or Hexagon.sides.

The only way to work with types and not instances is through reflection, so inheritance is not a concern.

If you are working with instances, define an abstract property then polymorphism can be used. For example:

public abstract class Shape
{
public abstract int Sides { get; }
}

public class Circle : Shape
{
public override int Sides => 1;
}

public class Hexagon : Shape
{
public override int Sides => 6;
}

Shape[] shapes = new Shape[] { new Circle(), new Hexagon() };
foreach (Shape shape in shapes)
{
Console.WriteLine($"Shape has {shape.Sides} sides");
}

I can't see any reason why you would make draw() static, unless it is a factory method, as it would require instance variables.

C# access children's static member in parent

I always feel like a jerk when I answer my own question... Yet didn't see what I was expecting so I might as well just share what I've got after a night of mind boggling.

The reason I don't want to make the calculation abstract/virtual is because there are many subclasses and the formula is the same for all of them. I just refuse to type the same code 10-20 times repeatedly.

Couldn't make the static fields non static either, as they should be accessible at a class level plus they can get big, and they are the same for all instances.

The only solution I can come up that minimizes code fragment is something like this

public class Foo {
public class Wrapper {
Fields...
}
public Wrapper wrapper; // reference
public int result1 { get; }
}

public class Bar : Foo {
public static Wrapper subclassWrapper; // put in the implementation
public Bar() : base(){
wrapper = subclassWrapper;
}
}

So each instance now needs to hold an extra reference, however I don't need to keep a function. The wrapper is kept within the base class so it is less fragmented.

What's the correct alternative to static method inheritance?

One idea:

public abstract class Fruit<T>
where T : Fruit<T>, new()
{
public static T CreateInstance()
{
T newFruit = new T();
newFruit.Initialize(); // Calls Apple.Initialize
return newFruit;
}

protected abstract void Initialize();
}

public class Apple : Fruit<Apple>
{
protected override void Initialize() { ... }
}

And call like so:

Apple myAppleVar = Fruit<Apple>.CreateInstance();

No extra factory classes needed.



Related Topics



Leave a reply



Submit