(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.
Related
I have found myself in a situation where I have a method on a base class which makes a call to a generic method passing itself as a parameter (via this). In the generic method the type is always the base type, even when I call the method from a derived class.
I need the generic method to know that it is of the derived type and not the base type.
I am not able to change the generic method since it is from a third party app (http://razorengine.codeplex.com/ - Razor.Parse method).
I have found that if I define the method as a generic extension method restricted to types inheriting from my base class that calling this then works but it seems messy to use extension methods for this purpose (though if this is correct usage I'd be happy to hear that). What I am wondering if there is some trick I can use that will convert "this" to the type of the derived object before it gets called (maybe using generics still).
I have included a simplified program below that should be self contained (I'm running it in LINQPad for personal ease). Essentially I want a method defined on A that when called on an instance of B will call Test.WhatType and output "B".
I hope this makes sense.
void Main()
{
var bar = new B();
bar.myGetType();
bar.ExtGetType();
}
class A
{
public virtual void myGetType()
{
Test.WhatType(this);
this.ExtGetType();
}
}
class B : A {}
static class ext
{
public static void ExtGetType<T>(this T obj) where T : A
{
Test.WhatType(obj);
}
}
class Test
{
public static void WhatType<T>(T obj)
{
Console.WriteLine(typeof(T).Name);
}
}
Edit: Changed method name to A.myGetType() since I hadn't even noticed I was overloading accidentally.
N.B. Running this code outputs:
A
A
B
You need to use obj.GetType(). T is bound at compile-time, not a run time and thus typeof(T) returns the compile-time type of T.
If I understand correctly, your problem is that A.GetType() is binding to WhatType<A> as that is all it knows about.
So you have to let class A know about the derived classes.
You can do this with self-referencing generic types. Something like:
class A<T> where T : A<T>
{
public virtual void GetType()
{
Test.WhatType<T>( (T) this );
}
}
class B : A<B> { }
then:
new B().GetType();
will bind to WhatType<B> and so will output B
This method returns the type of the static type (T). It should be implemented as
public static void WhatType<T>(T obj)
{
Console.WriteLine(obj.GetType().Name);
}
Edit:
I just realized what you want is to manipulate A in such a way that the T of the generic method changes. You can either do this via reflection or by adding a switch statement based on the subtype of A and explicitly cast this to B (or whatever class). Of course none of this solutions is good because A would take dependency on its subclasses and reflection plainly sux. Another option is to override the GetType() method in each subclass and thus move the responsibility to the subclasses.
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>();
}
}
I am working on a project, and I have a generic abstract type that takes a type parameter that is itself derived from the abstract type. If you want to know why I would do this, please see this question.
I have run into an interesting problem with overloading a method in a derived class that is defined in the abstract class. Here is a code sample:
public abstract class AbstractConverter<T, U>
where U : AbstractConvertible
where T : AbstractConverter<T, U>
{
public abstract T Convert(U convertible);
}
public class DerivedConvertibleConverter : AbstractConverter<DerivedConvertibleConverter, DerivedConvertible>
{
public DerivedConvertibleConverter(DerivedConvertible convertible)
{
Convert(convertible);
}
public override DerivedConvertibleConverter Convert(DerivedConvertible convertible)
{
//This will not be called
System.Console.WriteLine("Called the most derived method");
return this;
}
public DerivedConvertibleConverter Convert(Convertible convertible)
{
System.Console.WriteLine("Called the least derived method");
return this;
}
}
public abstract class AbstractConvertible {}
public class Convertible : AbstractConvertible {}
public class DerivedConvertible : Convertible {}
In the sample above, the overload of Convert that does not exist in the abstract parent (and is less derived) is called. I would expect that the most derived version, from the parent class, would be called.
In trying to troubleshoot this problem, I ran into an interesting solution:
public abstract class AbstractConverter<U>
where U : AbstractConvertible
{
public abstract AbstractConverter<U> Convert(U convertible);
}
public class DerivedConvertibleConverter : AbstractConverter<DerivedConvertible>
{
public DerivedConvertibleConverter(DerivedConvertible convertible)
{
Convert(convertible);
}
public override DerivedConvertibleConverter Convert(DerivedConvertible convertible)
{
System.Console.WriteLine("Called the most derived method");
return this;
}
public DerivedConvertibleConverter Convert(Convertible convertible)
{
System.Console.WriteLine("Called the least derived method");
return this;
}
}
public abstract class AbstractConvertible {}
public class Convertible : AbstractConvertible {}
public class DerivedConvertible : Convertible {}
When the derived type argument is removed from the base class, the most derived version of Convert is called. I would not expect this difference, since I would not have expected the interface of the abstract version of Convert to have changed. However, I must be wrong. Can anyone explain why this difference occurs? Thank you very much in advance.
In the sample above, the overload of Convert that does not exist in the abstract parent (and is less derived) is called. I would expect that the most derived version, from the parent class, would be called
Many people have this expectation. However, the behaviour you are observing is correct and by design.
The overload resolution algorithm goes like this. First we make a list of all the possible accessible methods you could be calling. Methods which override virtual methods are considered to be methods of the class which declared them, not the class which overrode them. Then we filter out the ones where the arguments cannot be converted to the formal parameter types. Then we filter out all the methods that are on any type less derived than any type that had an applicable method. Then we determine which method is better than another, if there is still more than one method left.
In your case there are two possible applicable methods. The one that takes a DerivedConvertible is considered to be a method of the base class, and is therefore not as good as the one that takes a Convertible.
The principle here is that overriding a virtual method is an implementation detail subject to change, and not a hint to the compiler that the overriding method is to be chosen.
More generally, these features of the overload resolution algorithm are designed to help mitigate various versions of the Brittle Base Class problem.
For more details about these design decisions see my article on the subject:
http://blogs.msdn.com/b/ericlippert/archive/2007/09/04/future-breaking-changes-part-three.aspx
When the derived type argument is removed from the base class, the most derived version of Convert is called. I would not expect this difference, since I would not have expected the interface of the abstract version of Convert to have changed
The question is based on a false premise; the most derived version is not called. The program fragment is erroneous, and therefore does not compile, and therefore neither method is called; the program doesn't run because it does not compile.
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
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