Reputation: 882
What is a design rationale behind this:
OK:
public class A
{
public virtual void DoWork() { Console.WriteLine("A"); }
}
public class B : A
{
private new void DoWork() { Console.WriteLine("B"); } //private works
}
public class C : B
{
public override void DoWork() { Console.WriteLine("C"); }
}
WRONG:
public class A
{
public virtual void DoWork() { Console.WriteLine("A"); }
}
public class B : A
{
public new void DoWork() { Console.WriteLine("B"); } //public doesn't
}
public class C : B
{
public override void DoWork() { Console.WriteLine("C"); }
}
Why does non-virtual method interfere with overriding virtual method anyway?
1st case: compiler checks that the method is private (new) so it allows class C.DoWork() to override class A.DoWork() (does not mix virtual and not-virtual (B.DoWork()) methods).
2nd case: compiler sees that public (new) void is declared and it arbitrarily(?) disrupts overriding in class C.
Now, if I wanted to declare new virtual DoWork() I could have done it, if I wanted to disallow overriding, I could have used sealed specifier. But in this case I wrote public void DoWork() as declaring normal non-virtual method and I do not expect it participating in virtual inheritance chain as in the private case. In 2nd example I expect:
A ac = new C();
ac.DoWork();
to print C as in the private case.
Upvotes: 1
Views: 110
Reputation: 1219
In below code
public class A
{
public virtual void DoWork() { Console.WriteLine("A"); }
}
public class B : A
{
private new void DoWork() { Console.WriteLine("B"); } //private works
}
public class C : B
{
public override void DoWork() { Console.WriteLine("C"); }
}
you are telling the compiler that DoWork() method in B class is a new
version of class A's DoWork() method. However, it allows you to override
DoWork in C due to the fact that you have declared DoWork's new
version as private in B which makes the compiler assume that that method is not exposed to the outside world.
However, in this,
public class A
{
public virtual void DoWork() { Console.WriteLine("A"); }
}
public class B : A
{
public new void DoWork() { Console.WriteLine("B"); } //public
}
public class C : B
{
public override void DoWork() { Console.WriteLine("C"); }
}
You are telling the compiler to override
new version of method DoWork(), which is a bit wrong from compiler's point of view as it cannot override
a non abstract
/virtual
/overriden
method as per the rules set while designing the language.
That is why, I think, your code gives error in one case and not the other.
Upvotes: 0
Reputation: 23626
In first example your C
class ovverides A's DoWork
(B
had DoWork, which is private and not visible to subclasses). In second example you hide DoWork
by non-virtual function and compiler complains, that you are trying to override non-virtual function. Solution is to expose families of virtual functions. By new virtual
you can create separations between these families.
public class B : A
{
public new virtual void DoWork() { Console.WriteLine("B"); } //private works
}
This code then
A a = new C();
a.DoWork();
prints A
B b = new C();
b.DoWork();
prints C
You can read in more detail how new virtual
is used in Knowing When to Use Override and New Keywords. new
keyword without virtual
has a different semantics from new virtual
, you can read more about it at new keyword in method signature.
Upvotes: 0
Reputation: 62256
Because in first case you're overriding an A
class function and not B
one
public class A
{
public virtual void DoWork() { Console.WriteLine("A"); }
}
public class B : A
{
private new void DoWork() { Console.WriteLine("B"); } //private works
}
public class C : B
{
public override void DoWork() { Console.WriteLine("C"); } //OVERRIDES A.DoWork()
}
You can not override non virtual
/abstract
methods of the base class.
Upvotes: 0