Tech Off Thread

18 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

Static Inheritance

Back to Forum: Tech Off
  • User profile image
    JoshB

    Can someone give me a good reason why C# doesn't support static inheritance. This seemed to me to be something very natural and like usual when I run into these kind of issues I find my design was all wrong.

    Without going into my specific context is there a quick answer and is the reason for lack of support more of a C# doesn't support it, or is it that it just doesn't make sense in OOP.

    I can elaborate if need be.

  • User profile image
    littleguru

    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?

  • User profile image
    JoshB

    That makes a lot of sense, and actually gives me a lot to go look up and learn.

    I'm wondering though, outside C# altogether, is there an object oriented reason that static inheritance would be bad. I'm thinking it is because I'm having a hard time coming up with a good example of how to use it, but I suck at good examples so I don't know.

  • User profile image
    littleguru

    From an OOP standpoint static inheritance shouldn't be considered. Inheritance works always on instance level. That has to do with the way how OOP is designed and the ideas behind it...

  • User profile image
    Sven Groot

    It's also a practical problem. Consider if this were possible:

    class A
    {
      public virtual static void Foo() { }
    }

    class B : A
    {
      public override static void Foo() { }
    }

    class C : A
    {
      public override static void Foo() { }
    }

    When the compiler now sees A.Foo(), how does it know which derived class to use? With regular virtual methods it does this because it gets the this pointer which contains the vtable for the actual type. With static methods, there's no such information available.

  • User profile image
    odujosh

    While you cannot override there are so instances where it is a good thing to have them inherited. One example I can think of is how I do my DAL.

    I have a static string PushNonQuery(SqlCommand command, string targetdatabase) written in a class I call BasicDALServices, which also hold a way to pass DataTables and Scalar back as well as the connection for any databases I may have. That way code that gets repeated ad infimitum throughout the DAL is typed coupled to a signal class that handles the code once.

  • User profile image
    littleguru

    odujosh wrote:
    While you cannot override there are so instances where it is a good thing to have them inherited. One example I can think of is how I do my DAL.

    I have a static string PushNonQuery(SqlCommand command, string targetdatabase) written in a class I call BasicDALServices, which also hold a way to pass DataTables and Scalar back as well as the connection for any databases I may have. That way code that gets repeated ad infimitum throughout the DAL is typed coupled to a signal class that handles the code once.


    Have you ever tried to use the singleton pattern? That should make your static override obsolete.

  • User profile image
    odujosh

    I never construct any part of my DAL. Thus instancing is not a concern. I have entity  based entry not single entry DAL manager approach that is particulairly appropriate to your suggestion.

  • User profile image
    RichardRudek

    My first CS program...

    So, would something like this be useful in CS ?:

    class A
    {
      public virtual void Foo() { }
    }

    class B : A
    {
      public override static void Foo() { MessageBox.Show("Class B"); }
    }

    class C : A
    {
      public override static void Foo() { MessageBox.Show("Class C"); }
    }


    Note the text in red. The point of this being that class A would be a "generic" base class, and classes B and C are "specialised" base classes. If you assign class B or C instance to an A class ref, calling A.Foo()  is a polymorphic call.

    Kind of like an Interface, but the child classes of B or C are not burdened with passing a this pointer. That is:

    B cB = new B();
    cB.Foo() // is a static call, no this.

    A cA = cB;
    cA.Foo(); // is polymorphic, passing cB.this.

  • User profile image
    Sven Groot

    In that example you're calling static methods using instance variables. That's not normally how you call static methods (at least, I've never done it, and the VB compiler even issues a warning if you do). Normally you would call with "A.Foo()" at which point the compiler has no idea whether it would need to call B.Foo or C.Foo instead.

    If you need to provide an instance for a "virtual" static call, then why use a static method in the first place?

  • User profile image
    littleguru

    Sven Groot wrote:
    In that example you're calling static methods using instance variables. That's not normally how you call static methods (at least, I've never done it, and the VB compiler even issues a warning if you do). Normally you would call with "A.Foo()" at which point the compiler has no idea whether it would need to call B.Foo or C.Foo instead.

    If you need to provide an instance for a "virtual" static call, then why use a static method in the first place?


    ++

    Expressionless I don't know why static inheritance would be useful. OOP is about instances and objects and encapsulation. Using a lot static methods is like falling back to procedural programming.

  • User profile image
    RichardRudek

    Sven Groot wrote:
    [snip]

    If you need to provide an instance for a "virtual" static call, then why use a static method in the first place?


    If the example was the full extent of the class heirachy, then it would be pointless. But consider when you need to build a 3rd, 4th or more tiers with the class heirachy ?

    I'm strugglling to think of an example. But let's try fruit. In which case, class A would be an Generic fruit object. Classes B and C would be particular types of fruit (Bananna, Cherries, etc), and children of either B or C classes would be further specialisations of those types of fruit. For example, Banannas from a particular region might be from a collective of growers, each collective requiring some common (fruit grower) data, but also some unique (collective) data (or visa versa - too early).

    If you have a class BG derived from class B, then from BG methods, you can call Foo() which should make a static call to B.Foo(). But if you now have some external helper routines, the helpers can be genericised (sp?) by making the helper take Class A object refs. When the helper calls A.Foo(), having been passed a BG object, it too will call B.Foo(), but having been resolved by a virtual table lookup.

    So the question is (taking into consideration that my example is probably to weak), would this type of class heirachy (data access layer?) be of any value, should static inheritance be possible ?

    Is "static inheritance" the right term for this ?

  • User profile image
    Sven Groot

    But you're still talking about passing objects (instances) around. The point of static methods is that you don't need an instance. I fail to see anything in your example that can't already be done with regular virtual instance methods. The question is then, what do virtual static methods add in your scenario? Why can't you just make Foo an instance method?

  • User profile image
    RichardRudek

    Sven Groot wrote:
    But you're still talking about passing objects (instances) around. The point of static methods is that you don't need an instance. I fail to see anything in your example that can't already be done with regular virtual instance methods. The question is then, what do virtual static methods add in your scenario? Why can't you just make Foo an instance method?


    Maybe I need to get some more sleep. But I'm not suggesting that these behaviours can't be done using exisitng methods. What I'm pointing out, perhaps badly, is that there is a possible performance and maintainence enhancement here.

    Firstly, if the general case is that the most specialised instance is the norm, the there's no vtable lookup - that's one of the advantages of a static method. There's a big penalty on A.Foo(), but BG.Foo() is a direct call.

    From a maintainence perspective, if your finding yourself cutting and pasting code between 2nd tier (specialised) classes, then I will typically look at moving this either into it's parent class, and occationally into helper routines, outside of the class heirachy, when there are data hiding/access or other issues. It's in this second case that there needs to be (explicit) object instances. Perhaps because I'm unfamilar with C#, this situation won't arise. But I've run into this situation with both C++ and Delphi more than a handfull of times. So it's not extremely rare.

    Anyway, I'll just step back and walk away now. Perhaps I should download and look at Anders' Object Dumper, referred in another thread, and see what he's doing.

    Have a good christmas, all.

  • User profile image
    Sven Groot

    Alright, you've completely lost me. I do not see at all what you want to use these static methods for or how they'd be implemented.

    If there need to be explicit object instances, then why can't you do it with instance methods? What exactly are you trying to achieve here?

  • User profile image
    littleguru

    RichardRudek wrote:
    Maybe I need to get some more sleep.


    Get some sleep Tongue Out

    RichardRudek wrote:
    But I'm not suggesting that these behaviours can't be done using exisitng methods. What I'm pointing out, perhaps badly, is that there is a possible performance and maintainence enhancement here.


    Well, well. Design guidelines suggest to create private static methods, if they don't access instance variables: that is really for performance reasons. But as said private static method that need no override!

    RichardRudek wrote:
    Firstly, if the general case is that the most specialised instance is the norm, the there's no vtable lookup - that's one of the advantages of a static method. There's a big penalty on A.Foo(), but BG.Foo() is a direct call.


    Is nobody using the sealed keyword when creating classes? That allows the runtime to eliminated vtables!

    RichardRudek wrote:
    From a maintainence perspective, if your finding yourself cutting and pasting code between 2nd tier (specialised) classes, then I will typically look at moving this either into it's parent class, and occationally into helper routines, outside of the class heirachy, when there are data hiding/access or other issues. It's in this second case that there needs to be (explicit) object instances. Perhaps because I'm unfamilar with C#, this situation won't arise. But I've run into this situation with both C++ and Delphi more than a handfull of times. So it's not extremely rare.


    I have been writing n-tier apps on my own and I didn't need static inheritance at all... It's most often only the design that lacks if you can't do something. You should step back and re-think the design. Design patterns help a lot!

    Creating to much static methods is like stepping back into procedural programming languages... All benefits of OOP get lost!

    RichardRudek wrote:
    Have a good christmas, all.


    You too Smiley

  • User profile image
    RichardRudek

    Wow, picking up my thought train is harder than I thought it would be.

    Anyway, I suppose I should state that, as far as I'm aware, what I'm talking about here is not possible with other compiled languages. And the use of this, is probably best described as a hack over the top of an existing library or framework. In other words, as little guru is suggesting, working around a bad or inappropriate design - real-world stuff... Smiley

    So at the first-tier of this class hierachy, class A is designed to use a virtual Foo(). As one then moves from this design, a realisation is made by the class B and C designer's that Foo() doesn't need to be virtual for the remainder of the hierachy. Instead, there only needs to a few "specialisations" of Foo(), which will satisfy all requirements. However, for one reason or another, we are not free to redesign class A.

    So the argument then becomes this, is there ANY benefit to being able to override class A's virtual Foo(), such that derivatives of class A, no longer need to implement a Foo().

    There are two possible benefits if you can, one performance, and one maintainence. But this is where my experience* with C# lets me down, and why I asked the question.

    * Actually, I should be saying inexperience.

    In Delphi and C++, the compilers are usually incapable of disambiguating these type of things to the point of eliminating vtable calls. So one would need to be explicit in the design. That's what I was (naively) coding for in the (experimental) C# example*.

    However, if littleguru is right, I'd be interested if in fact C# can do this, without explicit design. ie without the hack of an inheritable static. That is Foo() started as a virtual, but then became a static at next tier.

    * As this is a C# thought experiment, I haven't actually considered the Delphi and C++ solutions (workarounds) to this, yet.

    From the maintainence, perspective, it would be cool if we could leverage class A's original design of the virtual Foo(). It could be leveraged by "helper" routines, which are typically created when we find ourselves repeating (cutting and pasting) code, but also for things iterating, etc.

    In other words, there would likely be ways to do either one, but to do both, at the same time, would probably be more verbose - I still need more sleep, though... Wink

    And the question arises again, is what I'm talking about here, "static inheritance" ?  - perhaps it's just rambling, a solution looking for a problem ... Smiley

  • User profile image
    littleguru

    Well C#, and all MSIL in general, runs in a managed environment, which C/C++ and Delphi don't. .NET has also something called reflection, metadata that describes the assembly (dll, exe).

    But .NET allows to load assemblies during runtime. Assemblies that could override a virtual method, which makes removing of vtables harder.

    But since the JITTER (just in time compiler) runs during execution something can be done. I can't see why the JITTER should not remove vtables if encounting classes that are marked as sealed.

    It would also be possible to remove a lot of the vtables if all references are loaded (and no Assembly.LoadXXX is found in code). I don't know if that actually has been implemented - take quite a time to analyze code - but it should be possible to do.

    In general since the code is compiled during execution a lot of inlining and thus removing of vtables is possible! I'm sure the .NET runtime and JITTER guys have implemented a few routines to remove unecessary vtables Smiley

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.