Different behaviour of method overloading in C# - c#

I was going through C# Brainteasers (http://www.yoda.arachsys.com/csharp/teasers.html) and came across one question: what should be the output of this code?
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)");
}
}
class Test
{
static void Main()
{
Derived d = new Derived();
int i = 10;
d.Foo(i); // it prints ("Derived.Foo(object)"
}
}
But if I change the code to
class Derived
{
public void Foo(int x)
{
Console.WriteLine("Derived.Foo(int)");
}
public void Foo(object o)
{
Console.WriteLine("Derived.Foo(object)");
}
}
class Program
{
static void Main(string[] args)
{
Derived d = new Derived();
int i = 10;
d.Foo(i); // prints Derived.Foo(int)");
Console.ReadKey();
}
}
I want to why the output is getting changed when we are inheriting vs not inheriting; why is method overloading behaving differently in these two cases?

As I specified in the answers page:
Derived.Foo(object) is printed - when choosing an overload, if there are any compatible
methods declared in a derived class, all signatures declared in the base class are ignored
- even if they're overridden in the same derived class!
In other words, the compiler looks at methods which are freshly-declared in the most derived class (based on the compile-time type of the expression) and sees if any are applicable. If they are, it uses the "best" one available. If none is applicable, it tries the base class, and so on. An overridden method doesn't count as being declared in the derived class.
See sections 7.4.3 and 7.5.5.1 of the C# 3 spec for more details.
Now as for exactly why it's specified like that - I don't know. It makes sense to me that methods declared in the derived class take precedence over those declared in the base class, as otherwise you run into the "brittle base class" problem - adding a method in the base class could change the meaning of code using the derived class. However, if the derived class is overriding the method declared in the base class, it's clearly aware of it, so that element of brittleness doesn't apply.

It revolves around scope. In the first program, void Foo(int i) belongs to class Base. class Derived merely redefines its behavior.
Foo(int i) is ignored because it's being "borrowed" and redefined via inheritance from class Base. if Foo(object o) did not exist, then Foo(int i) would be used.
In the second program, void Foo(int i) is called because it properly belongs to class Derived (i.e. it's not being borrowed and overriden through inheritance) and has the best signature fit.

It's because the methods signatures in the derived class are matched first before considering the base class signatures. Therefore, when you try:
d.Foo(i);
It attempts to match the method signature against your current class (not the base class). It finds an acceptable match Foo(object) and doesn't further consider the base class method signatures.
It's all about the compiler finding a matching method signature, and the search order it uses to find these signatures.
-Doug

Related

Implementing covariant interface multiple times: is this behavior properly defined?

Given the following covariant generic interface
public interface IContainer<out T>
{
T Value { get; }
}
We can create a class that implements this interface multiple times for multiple generic types. In the scenario I'm interested about, these generic types share a common base type.
public interface IPrint
{
void Print();
}
public class PrintA : IPrint
{
public void Print()
{
Console.WriteLine("A");
}
}
public class PrintB : IPrint
{
public void Print()
{
Console.WriteLine("B");
}
}
public class SuperContainer : IContainer<PrintA>, IContainer<PrintB>
{
PrintA IContainer<PrintA>.Value => new PrintA();
PrintB IContainer<PrintB>.Value => new PrintB();
}
Now things get interesting when using this class through a reference of type IContainer<IPrint>.
public static void Main(string[] args)
{
IContainer<IPrint> container = new SuperContainer();
container.Value.Print();
}
This compiles and runs without issue and prints "A". What I've found in the spec:
The implementation of a particular interface member I.M, where I is
the interface in which the member M is declared, is determined by
examining each class or struct S, starting with C and repeating for
each successive base class of C, until a match is located:
If S
contains a declaration of an explicit interface member implementation
that matches I and M, then this member is the implementation of I.M.
Otherwise, if S contains a declaration of a non-static public member
that matches M, then this member is the implementation of I.M.
The first bullet point appears to be relevant, because the interface implementations are explicit. However, it doesn't say anything about which implementation is selected when there are multiple candidates.
It gets even more interesting if we use a public poperty for the IContainer<PrintA> implementation:
public class SuperContainer : IContainer<PrintA>, IContainer<PrintB>
{
public PrintA Value => new PrintA();
PrintB IContainer<PrintB>.Value => new PrintB();
}
Now, according to above spec, because there is an explicit interface implementation through IContainer<PrintB>, I would expect this to print "B". However, it is instead using the public property and still printing "A".
Similarly, if instead I implement IContainer<PrintA> explicitely and IContainer<PrintB> through public property, it still prints "A".
It appears that the only thing the output depends on is the order in which the interfaces are declared. If I change the declaration to
public class SuperContainer : IContainer<PrintB>, IContainer<PrintA>
everything prints "B"!
Which part of the spec defines this behavior, if it is properly defined at all?
I'm unable to find it in the specification, but what you're seeing is expected. IContainer<PrintA> and IContainer<PrintB> have different Fully Qualified Names (unable to find spec on how this FQN is formed) and so the compiler recognizes SuperContainer as an implementing class of two different interfaces, each having a void Print(); method.
So, we have two different interfaces each containing a method with the same signature. As you linked in the spec (13.4.2) the implementation of Print() is chosen first by looking at IContainer<PrintA>, looking for a proper mapping, and then looking at IContainer<PrintB>.
Since a proper mapping was found in IContainer<PrintA>, IContainer<PrintA>.Print() is used in SuperContainer's implimentation of IContainer<PrintB>.
From that same spec (located at the very bottom):
The members of a base class participate in interface mapping. In the example
interface Interface1
{
void F();
}
class Class1
{
public void F() {}
public void G() {}
}
class Class2: Class1, Interface1
{
new public void G() {}
}
the method F in Class1 is used in Class2's implementation of Interface1.
So in the end, yes the order is determining which Print() method is called.

Extension Method Overriding

Let's assume that I have two class.
public class A {...}
public class B : A {...}
What I want is to achieve is to override an extension function for both type.
public static void HelperExtension(this A a) {...}
public static void HelperExtension(this B b) {...}
I know that they are not virtual functions or behave like them. However I really wonder compiler behavior in this case.
Is there a way to call the function for type B without resolving its type? Or any auto-resolve suggestions?
This is not overriding - it is overloading, if anything.
It is fine - since the signatures are different, the compiler will not have any problem compiling it, even in the same namespace.
However, which extension method will be called depends on the exact type of the variable.
Now:
Is there a way to call the function for type B without resolving its type? Or any auto-resolve suggestions?
Without casting this is not possible. The extension is bound to the exact type that is being extended, so you need to have the exact type in order to call an extension on it.
This is why most of LINQ is defined on IEnumerable<T>.
As you said, there is no way of just making the extension virtual.
You could implement the entire virtual method pattern yourself through static methods but I have a strong feeling that's not going to be of any practical use to you, it's more of an interesting theoretical solution as the work involved would be prohibitive for something this simple.
If there are a fixed, finite number of possible sub classes you could have the first method have something like:
public static void HelperExtension(this A a)
{
B b = a as B;
if(b != null)
HelperExtension(b);
else
//the rest of the method.
}
You could use a Switch or even a Dictionary<Type, Action<A>> if you have a lot of subclasses, but it would be tedious, hard to maintain, and not support arbitrary inheritors not known at compile time.
Another option is to essentially leverage the compiler's functionality at compile time through the use of dynamic. I strongly advice avoiding it whenever possible, but in this particular case it would allow you to have a single public extension on A, a bunch of private static methods (with a different name) for each sub type, and then a single dispatch call:
public static void HelperExtension(this A a)
{
ExtenstionImplementation((dynamic)a);
}
private static void ExtenstionImplementation(A a){...}
private static void ExtenstionImplementation(B a){...}
private static void ExtenstionImplementation(C a){...}
I recently faced a similar problem. I have a third-party class library containing a hierarchy of class (let's say IBase, Base and Derived, where IBase is actually an interface).
public interface IBase {...}
public class Base : IBase {...}
public class Derived : Base {...}
Then, I have a class of mine which holds a reference ext to IBase. The concrete type of ext may be Base as well as Derived.
public class MyClass {
// other stuff
public IBase ext;
}
What I actually needed was a virtual method AddedMethod() defined within IBase and overridden in each descendant class, but that wasn't viable. So, one could be tempted to define a class containing a set of overloaded extension methods:
public static class MyExtensions
{
public static void AddedMethod(this IBase arg) {...}
public static void AddedMethod(this Base arg) {...}
public static void AddedMethod(this Derived arg) {...}
}
then, call ext.AddedMethod() on MyClass objects. This doesn't work: as extension methods are statically bound, the first method (i.e. AddedMethod(this IBase arg)) gets always called, regardless the actual type of ext.
The problem can be bypassed by defining a single extension method on IBase, then by using reflection to select the correct instance of a private static method whose argument type matches the actual type passed to the extension method:
public static class MyExtensions
{
// just one extension method
public static void AddedMethod(this IBase arg){
// get actual argument type
Type itsType = arg.GetType();
// select the proper inner method
MethodInfo mi = typeof(MyExtensions).GetMethod("innerAddedMethod",
BindingFlags.NonPublic | BindingFlags.Static,
null,
new Type[] { itsType },
null);
// invoke the selected method
if (mi != null) {
mi.Invoke(null, new object[] { arg });
}
}
private static void innerAddedMethod(Base arg) {
// code for Base type arg
}
private static void innerAddedMethod(Derived arg) {
// code for Derived type arg
}
Whether a new derived class Derived2 should be added to the IBase hierarchy, we'll have to simply add to MyExtensions class an overloaded innerAddedMethod() which takes Derived2 as its argument.

Derived method stronger than override in c#?

(again annoying question...)
after asking this before - ( which is partly related to my question) - i got an answer :
See ยง7.6.5.1 of the C# 4 spec:
The set of candidate methods is reduced to contain only methods from
the most derived types: For each method C.F in the set, where C is the
type in which the method F is declared, all methods declared in a base
type of C are removed from the set.
ok.
i have this code : //.Dump() is like a WriteLine command...
public class Base
{
public void Foo(string strings) { "1".Dump();}
public virtual void Foo(object strings) { "2".Dump();}
}
public class Child : Base
{
public override void Foo(object strings) { "4".Dump();}
}
but this code :
Child c = new Child();
c.Foo("d");
emits : "1"
but wait ...
didnt we say that is reduced to contain only methods from the most derived types: ?
Child has 1 function from its father public void Foo(string strings) and a NEARER override function.
so why did he choose its base's function ? does the inherited function is CLOSER than the override ?
is it related to the fact that override is at runtime ?
help please.
edit
what about this situation ?
public class Base
{
public virtual void Foo(int x) { "1".Dump();}
}
public class Child : Base
{
public override void Foo(int x) { "2".Dump();}
public void Foo(object x) { "3".Dump();}
}
void Main()
{
Child c = new Child();
c.Foo(6); //emits "3"
}
That's because your child takes an object.
public class Child : Base
{
public override void Foo(object strings) { "4".Dump();}
}
Make it string and then child one will be called.
public class Child : Base
{
public override void Foo(string strings) { "4".Dump();}
}
Why this?
Because compiler sees that child has object prameter it has to convert to string while in base class it is readily available as string.
So it calls base one.
Though Overridden function is nearer in the child class. But here rules are different in child and base. Child has object and base has string. It was fair if both had object or both had string.
I read this in Jon Skeet's C# in Depth Overloading Section
There are two concepts here which are being confused, overloading and overriding. Overloading is the concept of having multiple signatures for a function of the same name and choosing one to call based on that signature. Overriding is the concept of re-defining a method in a derived class.
Whether or not the child class overrode one of the method definitions does not matter at all to which function will be called because it does not change the signature of either method. By definition and construction overriding a method cannot change it's signature.
So, if the signature is unchanged exactly the same mechanics for determining the correct function to call based on the signature will be used against both the parent and child classes.
Update
In fact there is a little bit more to it as Eric Lippert points out in his blog. It turns out in fact that if there is a method that matches the overload in the child class it will not look for any methods in base classes. The reasons are sane - avoiding breaking changes - but the result is somewhat illogical when you own both the base and child class.
I can only echo Jon Skeet: "Given this oddness, my advice would be to avoid overloading across inheritance boundaries... at least with methods where more than one method could be applicable for a given call if you flattened the hierarchy"
You see here best match rule .
You pass a string like an argument to a Foo(..) function.
Base class has a Foo(string..), Child class, instead, has not. So the method of base is picked eventually , in this case.
I think here the base class method is chosen based on its dataType
As c.Foo("d"); matches exactly to the base class method and there is not any method overridden for it in the derived class therefore the base class method is called.

Compiler Trivia: What is consequence of this code

I was reviewing some code today and came across some code (accurately portrayed by this snippet)...
public abstract class FlargBase{
public FlargBase(){
this.DoSomething();
}
public abstract void DoSomething();
}
public class PurpleFlarg: FlargBase{
public PurpleFlarg()
: base(){
}
public override void DoSomething(){
// Do something here;
}
}
The compiler gives no errors or warnings, but CodeAnalysis warns that the call chain contains a call to a virtual method and may produce unintended results.
I was curious because, as I see it, two things can happen.
Creating an instance of the base class will make a call to a method with no defined implementation. I would expect the compiler to error, or the runtime to throw an exception due to a missing implementation. I'm assuming the compiler is providing an implementation of {} I mis-typed the original code; it did contain the abstract keyword on the class.
Creating an instance of a derived class will cause a call to a method on a class that has not actually been constructed yet. I would have expected this to throw an exception.
This code has been in a production environment for several months. It is apparently working correctly enough that no one has noticed any strange behavior.
I'm hoping the incredible talent here at StackOverflow can give me some insight into the behavior and consequences of this code.
A C# object is fully constructed and initialized to zero before the first constructor runs. The base constructor will call the derived implementation of the virtual method.
It's considered bad style to do this, because the derived implementation might behave strangely when the constructor of the derived class has not been called yet. But the behavior by itself is well defined. If you do nothing in the derived implementation that requires the code from the constructor to have already run, it will work.
You can image that the runtime calls the most derived constructor first. And its first action is to implicitly call the base constructor. I'm not sure if it's actually implemented like that, but since some .net languages allow you to call the base constructor at an arbitrary point of the derived constructor, I expect C# to simply call the base class constructor as first action of the derived constructor.
This behavior is very different from how C++ handles it. In C++ the derived classes get constructed one after the other, and before the constructor of the derived class has started the object has still the type of the baseclass and the overrides from the derived class are ignored.
Your PurpleFlarg.DoSomething() is executed before the PurpleFlarg() constructor body.
That can lead to surprises as the general assumption always is that the constructor is the first method to operate on an object.
Here is the MSDN page with an example of an 'error' condition.
In C#, override methods always resolve to the most derived implementation. An example is given in 10.11.3 (Constructor execution) of the C# spec here:
Variable initializers are transformed into assignment statements, and
these assignment statements are executed before the invocation of the
base class instance constructor. This ordering ensures that all
instance fields are initialized by their variable initializers before
any statements that have access to that instance are executed.
Given the example
using System;
class A
{
public A() {
PrintFields();
}
public virtual void PrintFields() {}
}
class B: A
{
int x = 1;
int y;
public B() {
y = -1;
}
public override void PrintFields() {
Console.WriteLine("x = {0}, y = {1}", x, y);
}
}
when new B() is used to create an instance of B, the following output
is produced:
x = 1, y = 0
If the class contains an abstract method (DoSomething), then the class has to be abstract too and cannot be instantiated.
Well, this pattern is really useful for overridable factories of objects in reality, so a case like the one in the next code seems to me perfectly legal and well written.
abstract class MyBase
{
public object CustomObject { get; private set; }
public MyBase()
{
this.CustomObject = this.CreateCustomObject();
}
protected abstract object CreateCustomObject();
}
class MyBaseList : MyBase
{
protected override object CreateCustomObject()
{
return new List<int>();
}
}
class MyBaseDict : MyBase
{
protected override object CreateCustomObject()
{
return new Dictionary<int, int>();
}
}

What is Shadowing?

In C# what does the term shadowing mean? I have read this link but didn't fully understand it.
Shadowing hides a method in a base class. Using the example in the question you linked:
class A
{
public int Foo(){ return 5;}
public virtual int Bar(){return 5;}
}
class B : A
{
public new int Foo() { return 1;}
public override int Bar() {return 1;}
}
Class B overrides the virtual method Bar. It hides (shadows) the non-virtual method Foo. Override uses the override keyword. Shadowing is done with the new keyword.
In the code above, if you didn't use the new keyword when defining the Foo method in class B, you would get this compiler warning:
'test.B.Foo()' hides inherited member 'test.A.Foo()'. Use the new keyword if hiding was intended.
Overriding : redefining an existing method on a base class
Shadowing : creating an entirely new method with the same signature as one in a base class
Suppose I have a base class that implements a virtual method:
public class A
{
public virtual void M() { Console.WriteLine("In A.M()."); }
}
I also have a derived class that also defines a method M:
public class B : A
{
// could be either "new" or "override", "new" is default
public void M() { Console.WriteLine("In B.M()."); }
}
Now, suppose I write a program like this:
A alpha = new B(); // it's really a B but I cast it to an A
alpha.M();
I have two different choices for how I want that to be implemented. The default behavior is to call A's version of M. (This is identical to the behavior if you applied the "new" keyword to B.M().)
This is called "shadowing" when we have a method with the same name but a different behavior when called from the base class.
Alternately, we could have specified "override" on B.M(). In this case, alpha.M() would have called B's version of M.
Shadowing consist on hiding a base class method with a new definition in a child class.
The difference between hiding and overriding has to do with the way methods are invoked.
That way, when a virtual method is overridden, the call address for the method call table of the base class is replaced with the address of the child routine.
On the other hand, when a method is hidden, a new address is added to the method call table of the child class.
When a call is made to the method in question:
The method call table class type is obtained, if we are invoking with a reference to the base class then the base class method table is obtained, if we have a reference to the child class, then the child class method table is obtained.
The method is searched in the table, if it's found then the invocation takes place, otherwise the base class method table is searched.
If we invoke the method with a reference to the child class then the behavior is the same, if the method has been overridden, the method address will be found in the base class, if the method was hidden the method address will be found on the child class, and since it has been already found, base class table will not be searched.
If we invoke the method with a reference to the base class then behavior changes. When overriding, as the method address overwrites base class entry, we will call the child method, even when holding a reference to the base class. With shadowing, the base class method table (which is the only one visible as we hold a reference to the base class) contains the virtual method address, and therefore, the base class method will be called.
In general shadowing is a bad idea, as it introduces a difference on the behavior of an instance depending on the reference we have to it.
Expanding on Kent's correct answer
When disambiguating when which method will be called, I like to think of shadowing vs. overriding with the following
Shadowing: The method called depends on the type of the reference at the point the call is made
Overriding: The method called depends on the type of the object at the point the call is made.
Here's an MSDN article on Shadowing. The language examples are in Visual Basic (unfortunately there is no equivalent C# page on MSDN), but it deals generally with the concepts and hopefully should help you understand anyway.
Edit: Seems like there is a C# article on shadowing, except that it's called hiding in C#. Also, this page offers a good overview.
If you want to hide Base class method , Use override in base [virtual method in base]
if you want to hide Child class method , Use new in base [nonvirtual method in base]->shadow
Base B=new Child()
B.VirtualMethod() -> Calls Child class method
B.NonVirtualMethod() -> Calls Base class method
Overriding: same name and exactly the same parameters, implemented
differently in sub classes.
If treated as DerivedClass or BaseClass, it used derived method.
Shadowing: same name and exactly the same parameters, implemented differently in sub classes.
If treated as DerivedClass, it used derived method.
if treated as BaseClass, it uses base method.
Hope this brief explanation helps.
Shadowing - Replaces the complete element of the parent class
class InventoryAndSales
{
public int InvoiceNumber { get; set; }
}
//if someone calls for this class then the InvoiceNumber type is now object
class NewInventoryAndSales : InventoryAndSales
{
public new object InvoiceNumber { get; set; }
}
Overriding - Only replaces the implementation. It doesn't replace the data type it doesn't replace like for example you have a variable it doesn't convert it into a method so if there is a method it will use that method and only changed the implementation
class InventoryAndSales
{
public virtual int GetTotalSales(int a, int b)
{
return a + b;
}
}
class NewInventoryAndSales : InventoryAndSales
{
//it replaces the implementation in parent class
public override int GetTotalSales(int a, int b)
{
return a * b;
}
}
Shadowing isn't something I'd be worried about understanding or implementing unless it "fits" the problem really well. I've seen it used improperly and cause weird logic bugs much more often than being used correctly. The big cause, I think, is when the programmer forgets to put overrides in a method signature then the compiler warning will suggest the new keyword. I've always felt that it should recommend using override instead.
private static int x = 10;
static void Main(string[] args)
{ int x = 20;
if (Program.x == 10)
{
Console.WriteLine(Program.x);
}
Console.WriteLine(x);}
Output:
10
20

Categories