C# method override resolution weirdness

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
6
down vote

favorite
3












Consider the following snippet of code:



using System;

class Base

public virtual void Foo(int x)

Console.WriteLine("Base.Foo(int)");



class Derived : Base

public override void Foo(int x)

Console.WriteLine("Derived.Foo(int)");


public void Foo(object o)

Console.WriteLine("Derived.Foo(object)");



public class Program

public static void Main()

Derived d = new Derived();
int i = 10;
d.Foo(i);




And the surprising output is:



Derived.Foo(object)


I would expect it to select the overridden Foo(int x) method, since it's more specific. However, C# compiler picks the non-inherited Foo(object o) version. This also causes a boxing operation.



What is the reason for this behaviour?










share|improve this question





















  • I've read this same question a few days ago, but can't find it anymore. The main point is, the compiler first checks for matching instance methods. The overridden methods still coutn as declared by the base class, so they would only be considered if there was no matching method declared in Derived, but Foo(object) does match. There was a blog by Jon Skeet (or maybe Eric Lippert) about that, still trying to find it
    – René Vogt
    3 hours ago










  • @RenéVogt: are you sure it's the compiler that checks it or the runtime?
    – Tim Schmelter
    3 hours ago






  • 1




    @TimSchmelter yes, the compiler. Found Jon Skeet's blog: csharpindepth.com/Articles/General/Overloading.aspx scroll down to "Inheritance".
    – René Vogt
    3 hours ago










  • @RenéVogt: i don't think it's that simple: stackoverflow.com/a/45872956/284240
    – Tim Schmelter
    3 hours ago










  • @TimSchmelter but that doesn't matter here, we don't talk about virtual methods because the compiler already choose to use the non-virtual instance method Foo(object). If this wouldn't exist, it would choose the virtual method and then the things you linked would happen at runtime.
    – René Vogt
    3 hours ago














up vote
6
down vote

favorite
3












Consider the following snippet of code:



using System;

class Base

public virtual void Foo(int x)

Console.WriteLine("Base.Foo(int)");



class Derived : Base

public override void Foo(int x)

Console.WriteLine("Derived.Foo(int)");


public void Foo(object o)

Console.WriteLine("Derived.Foo(object)");



public class Program

public static void Main()

Derived d = new Derived();
int i = 10;
d.Foo(i);




And the surprising output is:



Derived.Foo(object)


I would expect it to select the overridden Foo(int x) method, since it's more specific. However, C# compiler picks the non-inherited Foo(object o) version. This also causes a boxing operation.



What is the reason for this behaviour?










share|improve this question





















  • I've read this same question a few days ago, but can't find it anymore. The main point is, the compiler first checks for matching instance methods. The overridden methods still coutn as declared by the base class, so they would only be considered if there was no matching method declared in Derived, but Foo(object) does match. There was a blog by Jon Skeet (or maybe Eric Lippert) about that, still trying to find it
    – René Vogt
    3 hours ago










  • @RenéVogt: are you sure it's the compiler that checks it or the runtime?
    – Tim Schmelter
    3 hours ago






  • 1




    @TimSchmelter yes, the compiler. Found Jon Skeet's blog: csharpindepth.com/Articles/General/Overloading.aspx scroll down to "Inheritance".
    – René Vogt
    3 hours ago










  • @RenéVogt: i don't think it's that simple: stackoverflow.com/a/45872956/284240
    – Tim Schmelter
    3 hours ago










  • @TimSchmelter but that doesn't matter here, we don't talk about virtual methods because the compiler already choose to use the non-virtual instance method Foo(object). If this wouldn't exist, it would choose the virtual method and then the things you linked would happen at runtime.
    – René Vogt
    3 hours ago












up vote
6
down vote

favorite
3









up vote
6
down vote

favorite
3






3





Consider the following snippet of code:



using System;

class Base

public virtual void Foo(int x)

Console.WriteLine("Base.Foo(int)");



class Derived : Base

public override void Foo(int x)

Console.WriteLine("Derived.Foo(int)");


public void Foo(object o)

Console.WriteLine("Derived.Foo(object)");



public class Program

public static void Main()

Derived d = new Derived();
int i = 10;
d.Foo(i);




And the surprising output is:



Derived.Foo(object)


I would expect it to select the overridden Foo(int x) method, since it's more specific. However, C# compiler picks the non-inherited Foo(object o) version. This also causes a boxing operation.



What is the reason for this behaviour?










share|improve this question













Consider the following snippet of code:



using System;

class Base

public virtual void Foo(int x)

Console.WriteLine("Base.Foo(int)");



class Derived : Base

public override void Foo(int x)

Console.WriteLine("Derived.Foo(int)");


public void Foo(object o)

Console.WriteLine("Derived.Foo(object)");



public class Program

public static void Main()

Derived d = new Derived();
int i = 10;
d.Foo(i);




And the surprising output is:



Derived.Foo(object)


I would expect it to select the overridden Foo(int x) method, since it's more specific. However, C# compiler picks the non-inherited Foo(object o) version. This also causes a boxing operation.



What is the reason for this behaviour?







c# inheritance override






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 3 hours ago









Impworks

86621336




86621336











  • I've read this same question a few days ago, but can't find it anymore. The main point is, the compiler first checks for matching instance methods. The overridden methods still coutn as declared by the base class, so they would only be considered if there was no matching method declared in Derived, but Foo(object) does match. There was a blog by Jon Skeet (or maybe Eric Lippert) about that, still trying to find it
    – René Vogt
    3 hours ago










  • @RenéVogt: are you sure it's the compiler that checks it or the runtime?
    – Tim Schmelter
    3 hours ago






  • 1




    @TimSchmelter yes, the compiler. Found Jon Skeet's blog: csharpindepth.com/Articles/General/Overloading.aspx scroll down to "Inheritance".
    – René Vogt
    3 hours ago










  • @RenéVogt: i don't think it's that simple: stackoverflow.com/a/45872956/284240
    – Tim Schmelter
    3 hours ago










  • @TimSchmelter but that doesn't matter here, we don't talk about virtual methods because the compiler already choose to use the non-virtual instance method Foo(object). If this wouldn't exist, it would choose the virtual method and then the things you linked would happen at runtime.
    – René Vogt
    3 hours ago
















  • I've read this same question a few days ago, but can't find it anymore. The main point is, the compiler first checks for matching instance methods. The overridden methods still coutn as declared by the base class, so they would only be considered if there was no matching method declared in Derived, but Foo(object) does match. There was a blog by Jon Skeet (or maybe Eric Lippert) about that, still trying to find it
    – René Vogt
    3 hours ago










  • @RenéVogt: are you sure it's the compiler that checks it or the runtime?
    – Tim Schmelter
    3 hours ago






  • 1




    @TimSchmelter yes, the compiler. Found Jon Skeet's blog: csharpindepth.com/Articles/General/Overloading.aspx scroll down to "Inheritance".
    – René Vogt
    3 hours ago










  • @RenéVogt: i don't think it's that simple: stackoverflow.com/a/45872956/284240
    – Tim Schmelter
    3 hours ago










  • @TimSchmelter but that doesn't matter here, we don't talk about virtual methods because the compiler already choose to use the non-virtual instance method Foo(object). If this wouldn't exist, it would choose the virtual method and then the things you linked would happen at runtime.
    – René Vogt
    3 hours ago















I've read this same question a few days ago, but can't find it anymore. The main point is, the compiler first checks for matching instance methods. The overridden methods still coutn as declared by the base class, so they would only be considered if there was no matching method declared in Derived, but Foo(object) does match. There was a blog by Jon Skeet (or maybe Eric Lippert) about that, still trying to find it
– René Vogt
3 hours ago




I've read this same question a few days ago, but can't find it anymore. The main point is, the compiler first checks for matching instance methods. The overridden methods still coutn as declared by the base class, so they would only be considered if there was no matching method declared in Derived, but Foo(object) does match. There was a blog by Jon Skeet (or maybe Eric Lippert) about that, still trying to find it
– René Vogt
3 hours ago












@RenéVogt: are you sure it's the compiler that checks it or the runtime?
– Tim Schmelter
3 hours ago




@RenéVogt: are you sure it's the compiler that checks it or the runtime?
– Tim Schmelter
3 hours ago




1




1




@TimSchmelter yes, the compiler. Found Jon Skeet's blog: csharpindepth.com/Articles/General/Overloading.aspx scroll down to "Inheritance".
– René Vogt
3 hours ago




@TimSchmelter yes, the compiler. Found Jon Skeet's blog: csharpindepth.com/Articles/General/Overloading.aspx scroll down to "Inheritance".
– René Vogt
3 hours ago












@RenéVogt: i don't think it's that simple: stackoverflow.com/a/45872956/284240
– Tim Schmelter
3 hours ago




@RenéVogt: i don't think it's that simple: stackoverflow.com/a/45872956/284240
– Tim Schmelter
3 hours ago












@TimSchmelter but that doesn't matter here, we don't talk about virtual methods because the compiler already choose to use the non-virtual instance method Foo(object). If this wouldn't exist, it would choose the virtual method and then the things you linked would happen at runtime.
– René Vogt
3 hours ago




@TimSchmelter but that doesn't matter here, we don't talk about virtual methods because the compiler already choose to use the non-virtual instance method Foo(object). If this wouldn't exist, it would choose the virtual method and then the things you linked would happen at runtime.
– René Vogt
3 hours ago












2 Answers
2






active

oldest

votes

















up vote
8
down vote













This is the rule, and you may not like it,



Quote from Eric Lippert




if any method on a more-derived class is an applicable candidate, it
is automatically better than any method on a less-derived class, even
if the less-derived method has a better signature match.




The reason is because the method that is a better signature match might have been added in a later version and thereby be introducing a "brittle base class" failure




Note : this is a fairly complicated and in-depth part of the specs, and jumps all over the place, however the guts of it are written here



C#
Language Specification
Version 5.0




7.5.5 Function member invocation



...



The run-time processing of a function member invocation consists of
the following steps, where M is the function member and, if M is an
instance member, E is the instance expression:



...



If M is an instance function member declared in a reference-type:



  • E is evaluated. If this evaluation causes an exception, then no further steps are executed.

  • The argument list is evaluated as described in §7.5.1.

  • If the type of E is a value-type, a boxing conversion (§4.3.1) is performed to convert E to type object, and E is considered to be of
    type object in the following steps. In this case, M could only be a
    member of System.Object.

  • The value of E is checked to be valid. If the value of E is null, a System.NullReferenceException is thrown and no further steps are
    executed.

  • The function member implementation to invoke is determined:


    • If the binding-time type of E is an interface, the function member to invoke is the implementation of M provided by the run-time
      type of the instance referenced by E
      . This function member is
      determined by applying the interface mapping rules (§13.4.4) to
      determine the implementation of M provided by the run-time type of the
      instance referenced by E.

    • Otherwise, if M is a virtual function member, the function member to invoke is the implementation of M provided by the run-time type of
      the instance referenced by E. This function member is determined by
      applying the rules for determining the most derived implementation
      (§10.6.3) of M with respect to the run-time type of the instance
      referenced by E.

    • Otherwise, M is a non-virtual function member, and the function member to invoke is M itself.




What is interesting after reading the specs is, if you use an interface which describes the method, it will choose the overload signature and work as expected



 public interface ITest

void Foo(int x);



Which can be shown here



In regards to the interface, it does make sense when considering the overloading behavior was implemented to protect against Brittle base class




Additional Resources



Eric Lippert, Closer is better




The aspect of overload resolution in C# I want to talk about today is
really the fundamental rule by which one potential overload is judged
to be better than another for a given call site: closer is always
better than farther away. There are a number of ways to characterize
“closeness” in C#. Let’s start with the closest and move our way out:



  • A method first declared in a derived class is closer than a method first declared in a base class.

  • A method in a nested class is closer than a method in a containing class.

  • Any method of the receiving type is closer than any extension method.

  • An extension method found in a class in a nested namespace is closer than an extension method found in a class in an outer namespace.

  • An extension method found in a class in the current namespace is closer than an extension method found in a class in a namespace
    mentioned by a using directive.

  • An extension method found in a class in a namespace mentioned in a using directive where the directive is in a nested namespace is closer
    than an extension method found in a class in a namespace mentioned in
    a using directive where the directive is in an outer namespace.






share|improve this answer





























    up vote
    0
    down vote













    If you use a generic signature, you'il be comfortable.



     class Base

    public virtual void Foo<T>(T x)

    Console.WriteLine("Base.Foo(int)");



    class Derived : Base

    public override void Foo<T>(T x)









    share|improve this answer
















    • 3




      Doesn't explain this issue though
      – Tim Schmelter
      3 hours ago










    Your Answer





    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52661927%2fc-sharp-method-override-resolution-weirdness%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    8
    down vote













    This is the rule, and you may not like it,



    Quote from Eric Lippert




    if any method on a more-derived class is an applicable candidate, it
    is automatically better than any method on a less-derived class, even
    if the less-derived method has a better signature match.




    The reason is because the method that is a better signature match might have been added in a later version and thereby be introducing a "brittle base class" failure




    Note : this is a fairly complicated and in-depth part of the specs, and jumps all over the place, however the guts of it are written here



    C#
    Language Specification
    Version 5.0




    7.5.5 Function member invocation



    ...



    The run-time processing of a function member invocation consists of
    the following steps, where M is the function member and, if M is an
    instance member, E is the instance expression:



    ...



    If M is an instance function member declared in a reference-type:



    • E is evaluated. If this evaluation causes an exception, then no further steps are executed.

    • The argument list is evaluated as described in §7.5.1.

    • If the type of E is a value-type, a boxing conversion (§4.3.1) is performed to convert E to type object, and E is considered to be of
      type object in the following steps. In this case, M could only be a
      member of System.Object.

    • The value of E is checked to be valid. If the value of E is null, a System.NullReferenceException is thrown and no further steps are
      executed.

    • The function member implementation to invoke is determined:


      • If the binding-time type of E is an interface, the function member to invoke is the implementation of M provided by the run-time
        type of the instance referenced by E
        . This function member is
        determined by applying the interface mapping rules (§13.4.4) to
        determine the implementation of M provided by the run-time type of the
        instance referenced by E.

      • Otherwise, if M is a virtual function member, the function member to invoke is the implementation of M provided by the run-time type of
        the instance referenced by E. This function member is determined by
        applying the rules for determining the most derived implementation
        (§10.6.3) of M with respect to the run-time type of the instance
        referenced by E.

      • Otherwise, M is a non-virtual function member, and the function member to invoke is M itself.




    What is interesting after reading the specs is, if you use an interface which describes the method, it will choose the overload signature and work as expected



     public interface ITest

    void Foo(int x);



    Which can be shown here



    In regards to the interface, it does make sense when considering the overloading behavior was implemented to protect against Brittle base class




    Additional Resources



    Eric Lippert, Closer is better




    The aspect of overload resolution in C# I want to talk about today is
    really the fundamental rule by which one potential overload is judged
    to be better than another for a given call site: closer is always
    better than farther away. There are a number of ways to characterize
    “closeness” in C#. Let’s start with the closest and move our way out:



    • A method first declared in a derived class is closer than a method first declared in a base class.

    • A method in a nested class is closer than a method in a containing class.

    • Any method of the receiving type is closer than any extension method.

    • An extension method found in a class in a nested namespace is closer than an extension method found in a class in an outer namespace.

    • An extension method found in a class in the current namespace is closer than an extension method found in a class in a namespace
      mentioned by a using directive.

    • An extension method found in a class in a namespace mentioned in a using directive where the directive is in a nested namespace is closer
      than an extension method found in a class in a namespace mentioned in
      a using directive where the directive is in an outer namespace.






    share|improve this answer


























      up vote
      8
      down vote













      This is the rule, and you may not like it,



      Quote from Eric Lippert




      if any method on a more-derived class is an applicable candidate, it
      is automatically better than any method on a less-derived class, even
      if the less-derived method has a better signature match.




      The reason is because the method that is a better signature match might have been added in a later version and thereby be introducing a "brittle base class" failure




      Note : this is a fairly complicated and in-depth part of the specs, and jumps all over the place, however the guts of it are written here



      C#
      Language Specification
      Version 5.0




      7.5.5 Function member invocation



      ...



      The run-time processing of a function member invocation consists of
      the following steps, where M is the function member and, if M is an
      instance member, E is the instance expression:



      ...



      If M is an instance function member declared in a reference-type:



      • E is evaluated. If this evaluation causes an exception, then no further steps are executed.

      • The argument list is evaluated as described in §7.5.1.

      • If the type of E is a value-type, a boxing conversion (§4.3.1) is performed to convert E to type object, and E is considered to be of
        type object in the following steps. In this case, M could only be a
        member of System.Object.

      • The value of E is checked to be valid. If the value of E is null, a System.NullReferenceException is thrown and no further steps are
        executed.

      • The function member implementation to invoke is determined:


        • If the binding-time type of E is an interface, the function member to invoke is the implementation of M provided by the run-time
          type of the instance referenced by E
          . This function member is
          determined by applying the interface mapping rules (§13.4.4) to
          determine the implementation of M provided by the run-time type of the
          instance referenced by E.

        • Otherwise, if M is a virtual function member, the function member to invoke is the implementation of M provided by the run-time type of
          the instance referenced by E. This function member is determined by
          applying the rules for determining the most derived implementation
          (§10.6.3) of M with respect to the run-time type of the instance
          referenced by E.

        • Otherwise, M is a non-virtual function member, and the function member to invoke is M itself.




      What is interesting after reading the specs is, if you use an interface which describes the method, it will choose the overload signature and work as expected



       public interface ITest

      void Foo(int x);



      Which can be shown here



      In regards to the interface, it does make sense when considering the overloading behavior was implemented to protect against Brittle base class




      Additional Resources



      Eric Lippert, Closer is better




      The aspect of overload resolution in C# I want to talk about today is
      really the fundamental rule by which one potential overload is judged
      to be better than another for a given call site: closer is always
      better than farther away. There are a number of ways to characterize
      “closeness” in C#. Let’s start with the closest and move our way out:



      • A method first declared in a derived class is closer than a method first declared in a base class.

      • A method in a nested class is closer than a method in a containing class.

      • Any method of the receiving type is closer than any extension method.

      • An extension method found in a class in a nested namespace is closer than an extension method found in a class in an outer namespace.

      • An extension method found in a class in the current namespace is closer than an extension method found in a class in a namespace
        mentioned by a using directive.

      • An extension method found in a class in a namespace mentioned in a using directive where the directive is in a nested namespace is closer
        than an extension method found in a class in a namespace mentioned in
        a using directive where the directive is in an outer namespace.






      share|improve this answer
























        up vote
        8
        down vote










        up vote
        8
        down vote









        This is the rule, and you may not like it,



        Quote from Eric Lippert




        if any method on a more-derived class is an applicable candidate, it
        is automatically better than any method on a less-derived class, even
        if the less-derived method has a better signature match.




        The reason is because the method that is a better signature match might have been added in a later version and thereby be introducing a "brittle base class" failure




        Note : this is a fairly complicated and in-depth part of the specs, and jumps all over the place, however the guts of it are written here



        C#
        Language Specification
        Version 5.0




        7.5.5 Function member invocation



        ...



        The run-time processing of a function member invocation consists of
        the following steps, where M is the function member and, if M is an
        instance member, E is the instance expression:



        ...



        If M is an instance function member declared in a reference-type:



        • E is evaluated. If this evaluation causes an exception, then no further steps are executed.

        • The argument list is evaluated as described in §7.5.1.

        • If the type of E is a value-type, a boxing conversion (§4.3.1) is performed to convert E to type object, and E is considered to be of
          type object in the following steps. In this case, M could only be a
          member of System.Object.

        • The value of E is checked to be valid. If the value of E is null, a System.NullReferenceException is thrown and no further steps are
          executed.

        • The function member implementation to invoke is determined:


          • If the binding-time type of E is an interface, the function member to invoke is the implementation of M provided by the run-time
            type of the instance referenced by E
            . This function member is
            determined by applying the interface mapping rules (§13.4.4) to
            determine the implementation of M provided by the run-time type of the
            instance referenced by E.

          • Otherwise, if M is a virtual function member, the function member to invoke is the implementation of M provided by the run-time type of
            the instance referenced by E. This function member is determined by
            applying the rules for determining the most derived implementation
            (§10.6.3) of M with respect to the run-time type of the instance
            referenced by E.

          • Otherwise, M is a non-virtual function member, and the function member to invoke is M itself.




        What is interesting after reading the specs is, if you use an interface which describes the method, it will choose the overload signature and work as expected



         public interface ITest

        void Foo(int x);



        Which can be shown here



        In regards to the interface, it does make sense when considering the overloading behavior was implemented to protect against Brittle base class




        Additional Resources



        Eric Lippert, Closer is better




        The aspect of overload resolution in C# I want to talk about today is
        really the fundamental rule by which one potential overload is judged
        to be better than another for a given call site: closer is always
        better than farther away. There are a number of ways to characterize
        “closeness” in C#. Let’s start with the closest and move our way out:



        • A method first declared in a derived class is closer than a method first declared in a base class.

        • A method in a nested class is closer than a method in a containing class.

        • Any method of the receiving type is closer than any extension method.

        • An extension method found in a class in a nested namespace is closer than an extension method found in a class in an outer namespace.

        • An extension method found in a class in the current namespace is closer than an extension method found in a class in a namespace
          mentioned by a using directive.

        • An extension method found in a class in a namespace mentioned in a using directive where the directive is in a nested namespace is closer
          than an extension method found in a class in a namespace mentioned in
          a using directive where the directive is in an outer namespace.






        share|improve this answer














        This is the rule, and you may not like it,



        Quote from Eric Lippert




        if any method on a more-derived class is an applicable candidate, it
        is automatically better than any method on a less-derived class, even
        if the less-derived method has a better signature match.




        The reason is because the method that is a better signature match might have been added in a later version and thereby be introducing a "brittle base class" failure




        Note : this is a fairly complicated and in-depth part of the specs, and jumps all over the place, however the guts of it are written here



        C#
        Language Specification
        Version 5.0




        7.5.5 Function member invocation



        ...



        The run-time processing of a function member invocation consists of
        the following steps, where M is the function member and, if M is an
        instance member, E is the instance expression:



        ...



        If M is an instance function member declared in a reference-type:



        • E is evaluated. If this evaluation causes an exception, then no further steps are executed.

        • The argument list is evaluated as described in §7.5.1.

        • If the type of E is a value-type, a boxing conversion (§4.3.1) is performed to convert E to type object, and E is considered to be of
          type object in the following steps. In this case, M could only be a
          member of System.Object.

        • The value of E is checked to be valid. If the value of E is null, a System.NullReferenceException is thrown and no further steps are
          executed.

        • The function member implementation to invoke is determined:


          • If the binding-time type of E is an interface, the function member to invoke is the implementation of M provided by the run-time
            type of the instance referenced by E
            . This function member is
            determined by applying the interface mapping rules (§13.4.4) to
            determine the implementation of M provided by the run-time type of the
            instance referenced by E.

          • Otherwise, if M is a virtual function member, the function member to invoke is the implementation of M provided by the run-time type of
            the instance referenced by E. This function member is determined by
            applying the rules for determining the most derived implementation
            (§10.6.3) of M with respect to the run-time type of the instance
            referenced by E.

          • Otherwise, M is a non-virtual function member, and the function member to invoke is M itself.




        What is interesting after reading the specs is, if you use an interface which describes the method, it will choose the overload signature and work as expected



         public interface ITest

        void Foo(int x);



        Which can be shown here



        In regards to the interface, it does make sense when considering the overloading behavior was implemented to protect against Brittle base class




        Additional Resources



        Eric Lippert, Closer is better




        The aspect of overload resolution in C# I want to talk about today is
        really the fundamental rule by which one potential overload is judged
        to be better than another for a given call site: closer is always
        better than farther away. There are a number of ways to characterize
        “closeness” in C#. Let’s start with the closest and move our way out:



        • A method first declared in a derived class is closer than a method first declared in a base class.

        • A method in a nested class is closer than a method in a containing class.

        • Any method of the receiving type is closer than any extension method.

        • An extension method found in a class in a nested namespace is closer than an extension method found in a class in an outer namespace.

        • An extension method found in a class in the current namespace is closer than an extension method found in a class in a namespace
          mentioned by a using directive.

        • An extension method found in a class in a namespace mentioned in a using directive where the directive is in a nested namespace is closer
          than an extension method found in a class in a namespace mentioned in
          a using directive where the directive is in an outer namespace.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 15 mins ago

























        answered 3 hours ago









        Saruman

        20.7k52658




        20.7k52658






















            up vote
            0
            down vote













            If you use a generic signature, you'il be comfortable.



             class Base

            public virtual void Foo<T>(T x)

            Console.WriteLine("Base.Foo(int)");



            class Derived : Base

            public override void Foo<T>(T x)









            share|improve this answer
















            • 3




              Doesn't explain this issue though
              – Tim Schmelter
              3 hours ago














            up vote
            0
            down vote













            If you use a generic signature, you'il be comfortable.



             class Base

            public virtual void Foo<T>(T x)

            Console.WriteLine("Base.Foo(int)");



            class Derived : Base

            public override void Foo<T>(T x)









            share|improve this answer
















            • 3




              Doesn't explain this issue though
              – Tim Schmelter
              3 hours ago












            up vote
            0
            down vote










            up vote
            0
            down vote









            If you use a generic signature, you'il be comfortable.



             class Base

            public virtual void Foo<T>(T x)

            Console.WriteLine("Base.Foo(int)");



            class Derived : Base

            public override void Foo<T>(T x)









            share|improve this answer












            If you use a generic signature, you'il be comfortable.



             class Base

            public virtual void Foo<T>(T x)

            Console.WriteLine("Base.Foo(int)");



            class Derived : Base

            public override void Foo<T>(T x)










            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered 3 hours ago









            Sinan BARAN

            59628




            59628







            • 3




              Doesn't explain this issue though
              – Tim Schmelter
              3 hours ago












            • 3




              Doesn't explain this issue though
              – Tim Schmelter
              3 hours ago







            3




            3




            Doesn't explain this issue though
            – Tim Schmelter
            3 hours ago




            Doesn't explain this issue though
            – Tim Schmelter
            3 hours ago

















             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52661927%2fc-sharp-method-override-resolution-weirdness%23new-answer', 'question_page');

            );

            Post as a guest













































































            Comments

            Popular posts from this blog

            White Anglo-Saxon Protestant

            Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

            One-line joke