C# method override resolution weirdness

Clash Royale CLAN TAG#URR8PPP
up vote
6
down vote
favorite
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
 |Â
show 1 more comment
up vote
6
down vote
favorite
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
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 inDerived, butFoo(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 methodFoo(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
 |Â
show 1 more comment
up vote
6
down vote
favorite
up vote
6
down vote
favorite
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
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
c# inheritance override
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 inDerived, butFoo(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 methodFoo(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
 |Â
show 1 more comment
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 inDerived, butFoo(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 methodFoo(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
 |Â
show 1 more comment
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.
add a comment |Â
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)
3
Doesn't explain this issue though
â Tim Schmelter
3 hours ago
add a comment |Â
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.
add a comment |Â
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.
add a comment |Â
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.
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.
edited 15 mins ago
answered 3 hours ago
Saruman
20.7k52658
20.7k52658
add a comment |Â
add a comment |Â
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)
3
Doesn't explain this issue though
â Tim Schmelter
3 hours ago
add a comment |Â
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)
3
Doesn't explain this issue though
â Tim Schmelter
3 hours ago
add a comment |Â
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)
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)
answered 3 hours ago
Sinan BARAN
59628
59628
3
Doesn't explain this issue though
â Tim Schmelter
3 hours ago
add a comment |Â
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
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password

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, butFoo(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