c# - optional parameter: reversed precedence if override of overload exists -
i wonder following behavior:
public class { public virtual void do() { console.writeline("a"); } } public class b : { public override void do() { console.writeline("b override"); } public void do(int value = 0) { console.writeline("b overload"); } } class program { public static void main() { new b().do(); // ---> console: "b overload" } }
i expect overload exact signature has precedence on overload optional parameters: expect "b override" in console. instead program writes "b overload" console.
even resharper fails , falls trap:
... resharper says overload optional parameter hidden overload exact signature, in fact contrary.
now, if remove inheritance, behaves expected , resharper warning legitimate:
public class b { public virtual void do() { console.writeline("b override"); } public void do(int value = 0) { console.writeline("b overload"); } } class program { public static void main() { new b().do(); // ---> console: "b override" } }
so question: precedence rule explains observation? why overload exact signature doesn't have precedence on overload optional parameters in case overload exact parameters overrides base implementation?
why overload exact signature doesn't have precedence on overload optional parameters in case overload exact parameters overrides base implementation?
basically compiler following rules of specification, though they're surprising in case. (section 7.6.5.1 relevant part of c# 5 spec.)
the compiler looks @ "deepest" type first - i.e. 1 compile-time type of target (b
in case) , tries find applicable function member ignoring methods override declared in base class:
the set of candidate methods reduced contain methods derived types: each method c.f in set, c type in method f declared, methods declared in base type of c removed set.
and:
the intuitive effect of resolution rules described above follows: locate particular method invoked method invocation, start type indicated method invocation , proceed inheritance chain until @ least 1 applicable, accessible, non-override method declaration found. perform type inference , overload resolution on set of applicable, accessible, non-override methods declared in type , invoke method selected. if no method found, try instead process invocation extension method invocation.
so in case, compiler only considers newly-introduced method, finds it's applicable (using default parameter value) , stops search. (i.e. doesn't @ methods declared in base classes). @ point, set of candidate function members has 1 entry, there's no real overload resolution perform @ point.
i have article on overloading shows sort of thing, not using optional parameter using different parameter type - see "inheritance" section.
Comments
Post a Comment