none
Inheritance and static members

    Question

  • Hi all,

     

    I found strange that inheritance applies to static members in C#. For example

     

    Code Snippet

    Public Class A

    {

    public static Method1()

    {}

    }

     

    Public Class B : A

    {}

     

    Public Class Program

    {

    static void main()

    {

    B.Method1();

    }

    }

     

     

    Why does C# allows type B to access its base class static method? I understand Static members are specific to a type and confused why inheritance is applied with derived types.

     

    Please share your comments.

     

    Thanks,

    Suresh.

    Monday, August 13, 2007 12:04 PM

Answers

  • Anybody can access A.Method1(), it's public.  Why not B?  A derived class inherits every property, field and method of its base class.  If they would make a special rule for static members, you'd have to constantly provide the type name of the base class.  That wouldn't make your code more reliable, just less maintainable.  Use "internal" to hide the method from your class clients.
    Monday, August 13, 2007 7:02 PM
    Moderator
  • Add C++ to that list.  This would have compiled without problem back in 1993 and compiles now:

    class A {
    public:
      static void Method1() {}
    };

    class B : A {
    public:
      B() {
        B::Method1();
      }
    };

    Inheritance is whole-sale, you inherit everything from the base class.
    Tuesday, August 14, 2007 1:24 PM
    Moderator

All replies

  • - If you look at the generated IL you will see that the compiler silently compiled it as A.Method1()
    -> thus there is no inheritance...

    (I would consider it a convenience..  but i can imagine that other people see that completely different)

    Monday, August 13, 2007 3:38 PM
  • Anybody can access A.Method1(), it's public.  Why not B?  A derived class inherits every property, field and method of its base class.  If they would make a special rule for static members, you'd have to constantly provide the type name of the base class.  That wouldn't make your code more reliable, just less maintainable.  Use "internal" to hide the method from your class clients.
    Monday, August 13, 2007 7:02 PM
    Moderator
  • Hi Tim,

     

    I could not able to agree that since the compiler compiled it as A.Method1() there is no inheritance.I can see that the compiler is still compiling it as A.Method1() even if the method is declared as non-static.

     

    Hi Hans,

     

    I agree that anybody can access A.Method1() and my question is not related to aceess modifiers.Why does the inheritance applied at the type level?What is the advantage you get when you acccess it as B.Method1() rather than A.Method1()? Syntactic convenience? or to establish is-a relationship?

     

    I also read the following post which says this feature is C# specific and CLR's and not supported by other .NET languages.

     

    http://weblogs.asp.net/okloeten/archive/2004/07/06/174196.aspx

     

    I tried the same in VB and it works the same way as C# does.

     

    Any thoughts welcome.

     

    Thanks,
    Suresh.

     

     

     

     

    Tuesday, August 14, 2007 12:40 PM
  • Add C++ to that list.  This would have compiled without problem back in 1993 and compiles now:

    class A {
    public:
      static void Method1() {}
    };

    class B : A {
    public:
      B() {
        B::Method1();
      }
    };

    Inheritance is whole-sale, you inherit everything from the base class.
    Tuesday, August 14, 2007 1:24 PM
    Moderator
  • So, i've been doing some research...

    http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-335.pdf
    (CLI 8.10.2 Method inheritance)


    A derived object type inherits all of the instance and virtual methods of its base object type. It does not inherit
    constructors or static methods....


    In http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf (C#  17.2.1 Inheritance)


    A class inherits the members of its direct base class. Inheritance means that a class implicitly contains all
    members of its direct base class, except for the instance constructors, finalizers, and static constructors of the
    base class




    Tuesday, August 14, 2007 3:18 PM
  • Okay, here's the same code in C++/CLI.  It compiles:

    ref class A {
    public:
      static void Method1() {}
    };

    ref class B : A {
    public:
      B() {
        B::Method1();
      }
    };

    Either C++/CLI, VB.NET and C# (and IntelliSense) are not standard compliant or we got the wrong idea about scope resolution.
    Tuesday, August 14, 2007 4:17 PM
    Moderator
  • I think it comes down to a matter of perspective:

    - As already shown, from a C++ (or VB.NET or C#) perspective you inherit "everything" and the call B::Method1() is resolved...

    - From an IL point of view you see that the code is translated as a call on A (whereas a non-static method would have been translated as a callvirt on A)


    I don't see why this would imply that C++/CLI, VB.NET and C#  aren't standard compliant... It's just that in their standard the definition of inheritance seems to be different than the one given in the CLI spec...




    Think about the following:

    Code Snippet

    class A { public static int X = 0; };
    class B : A { };

    // when 'everything' is inherited, there should be a field X that is coupled to type B and one that is coupled to type A

    class Program
    {
     static void Main(string[] args)
     {
      B.X = 10;
      Console.WriteLine(A.X); // notice that this is 10 and not the expected 0
     }
    }




    Tuesday, August 14, 2007 6:25 PM