Derived classes and overloaded methods

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Random.Coder@gmail.com

    Derived classes and overloaded methods

    The output of this simple program below differs if it's compiled in
    Visual Studio 2005 and 2008. Is one the correct output, and if so,
    why?

    using System;

    namespace DerivedTestApp
    {
    class BaseClass
    {
    static public void Test(uint a)
    {
    Console.WriteLi ne("(BaseClass ) uint: {0}", a);
    }
    }

    class DerivedClass : BaseClass
    {
    public enum TestEnum
    {
    Alpha,
    Beta,
    }

    static public void Test(TestEnum a)
    {
    string s = "Error";
    switch (a)
    {
    case TestEnum.Alpha: s = "Alpha"; break;
    case TestEnum.Beta: s = "Beta"; break;
    }
    Console.WriteLi ne("(DerivedCla ss) TestEnum: {0}", s);
    }
    }

    class Program
    {
    static void Main()
    {
    DerivedClass.Te st((uint)0);
    DerivedClass.Te st(DerivedClass .TestEnum.Alpha );
    }
    }
    }

    // -- Visual studio 2005:
    //(BaseClass) uint: 0
    //(DerivedClass) TestEnum: Alpha
    // -- Visual studio 2008:
    //(DerivedClass) TestEnum: Alpha
    //(DerivedClass) TestEnum: Alpha
  • Peter Duniho

    #2
    Re: Derived classes and overloaded methods

    On Fri, 25 Apr 2008 10:37:39 -0700, <Random.Coder@g mail.comwrote:
    The output of this simple program below differs if it's compiled in
    Visual Studio 2005 and 2008. Is one the correct output, and if so,
    why?
    It's a known "breaking change" for VS2008. See


    The short answer is (from the above document): "All constant expressions
    equal to 0 are now implicitly convertible to enum types"

    In other words, even though you cast your 0 to "uint", the compiler is
    able to implicitly convert it to an enum type. Since you're calling the
    method from the derived class, the compiler prefers the overload found in
    that class, and since it can implicitly convert the 0 to the appropriate
    enum type now, it does.

    Pete

    Comment

    • Random.Coder@gmail.com

      #3
      Re: Derived classes and overloaded methods

      On Apr 25, 10:45 am, "Peter Duniho" <NpOeStPe...@nn owslpianmk.com>
      wrote:
      On Fri, 25 Apr 2008 10:37:39 -0700, <Random.Co...@g mail.comwrote:
      The output of this simple program below differs if it's compiled in
      Visual Studio 2005 and 2008.  Is one the correct output, and if so,
      why?
      >
      The short answer is (from the above document): "All constant expressions  
      equal to 0 are now implicitly convertible to enum types"
      Thanks!

      Comment

      • parez

        #4
        Re: Derived classes and overloaded methods

        On Apr 25, 1:45 pm, "Peter Duniho" <NpOeStPe...@nn owslpianmk.com>
        wrote:
        On Fri, 25 Apr 2008 10:37:39 -0700, <Random.Co...@g mail.comwrote:
        The output of this simple program below differs if it's compiled in
        Visual Studio 2005 and 2008. Is one the correct output, and if so,
        why?
        >
        It's a known "breaking change" for VS2008. See http://download.microsoft.com/downlo...789-411c-a367-...
        >
        The short answer is (from the above document): "All constant expressions
        equal to 0 are now implicitly convertible to enum types"
        >
        In other words, even though you cast your 0 to "uint", the compiler is
        able to implicitly convert it to an enum type. Since you're calling the
        method from the derived class, the compiler prefers the overload found in
        that class, and since it can implicitly convert the 0 to the appropriate
        enum type now, it does.
        >
        Pete
        will the same difference be reflected in overloaded functions with
        int some1(SomeEnum a)
        int some1(uint a)

        Comment

        • Peter Duniho

          #5
          Re: Derived classes and overloaded methods

          On Fri, 25 Apr 2008 12:56:10 -0700, parez <psawant@gmail. comwrote:
          will the same difference be reflected in overloaded functions with
          int some1(SomeEnum a)
          int some1(uint a)
          I'm not sure what you're asking. What's the difference between that and
          the OP's question? Do you mean if the methods are both in the same
          class? If so, I think the answer is "yes".

          In fact, reviewing the overload resolution rules, I think I might have
          been misstating the rule to say that a method in a more-derived class has
          precedence. I didn't see a rule in the C# 3.0 spec that says that.
          However, it _does_ say that a more-specific type takes precedence over a
          less-specific type. That's probably the rule at work here -- the enum is
          more specific than the uint -- and that rule would apply whether the
          methods are declared in the same class, or in different classes within the
          inheritance hierarchy.

          Pete

          Comment

          • Jon Skeet [C# MVP]

            #6
            Re: Derived classes and overloaded methods

            Peter Duniho <NpOeStPeAdM@nn owslpianmk.comw rote:
            In fact, reviewing the overload resolution rules, I think I might have
            been misstating the rule to say that a method in a more-derived class has
            precedence.
            It's somewhat buried. Basically if an applicable method is *first
            declared* (i.e. not overridden) in a more derived class, *all*
            applicable methods first declared in base classes are ignored. It leads
            to very unintuitive cases, such as this:

            using System;

            class Base
            {
            public virtual void Foo(int x)
            {
            Console.WriteLi ne("Base.Foo(in t)");
            }
            }

            class Derived : Base
            {
            public override void Foo(int x)
            {
            Console.WriteLi ne("Derived.Foo (int)");
            }

            public void Foo(object x)
            {
            Console.WriteLi ne("Derived.Foo (object)");
            }
            }

            class Test
            {
            static void Main()
            {
            new Derived().Foo(1 );
            }
            }

            --
            Jon Skeet - <skeet@pobox.co m>
            http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
            World class .NET training in the UK: http://iterativetraining.co.uk

            Comment

            • Peter Duniho

              #7
              Re: Derived classes and overloaded methods

              On Sat, 26 Apr 2008 13:20:21 -0700, Jon Skeet [C# MVP] <skeet@pobox.co m>
              wrote:
              Peter Duniho <NpOeStPeAdM@nn owslpianmk.comw rote:
              >In fact, reviewing the overload resolution rules, I think I might have
              >been misstating the rule to say that a method in a more-derived class
              >has
              >precedence.
              >
              It's somewhat buried. Basically if an applicable method is *first
              declared* (i.e. not overridden) in a more derived class, *all*
              applicable methods first declared in base classes are ignored. It leads
              to very unintuitive cases, such as this: [snip]
              Ahh...so I wasn't just imagining things. And yes, I agree that the
              example you showed isn't completely intuitive. I do kind of understand
              why the rule is the way it is. But it's not immediately obvious why it
              makes sense that the hierarchy-based rule takes precedence over the "more
              specific type" rule.

              Anyway, thanks for the clarification. Good stuff. :)

              Pete

              Comment

              • Jon Skeet [C# MVP]

                #8
                Re: Derived classes and overloaded methods

                Peter Duniho <NpOeStPeAdM@nn owslpianmk.comw rote:
                It's somewhat buried. Basically if an applicable method is *first
                declared* (i.e. not overridden) in a more derived class, *all*
                applicable methods first declared in base classes are ignored. It leads
                to very unintuitive cases, such as this: [snip]
                >
                Ahh...so I wasn't just imagining things. And yes, I agree that the
                example you showed isn't completely intuitive. I do kind of understand
                why the rule is the way it is.
                I understand it when there *isn't* an override in the derived class
                (otherwise you have a versioning issue if a base class adds an overload
                unexpectedly) but when there *is* an override, it's clear that the
                derived class knows about the base class's method, so at that point I
                see no reason to exclude that signature.
                But it's not immediately obvious why it makes sense that the
                hierarchy-based rule takes precedence over the "more specific type"
                rule.
                Right.
                Anyway, thanks for the clarification. Good stuff. :)
                I'm just glad you haven't asked me where it is in the spec. It's
                definitely there somewhere, but it always takes me a while to find!

                --
                Jon Skeet - <skeet@pobox.co m>
                http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
                World class .NET training in the UK: http://iterativetraining.co.uk

                Comment

                Working...