You have an error in your C# code.
To override a C# function you have to specify the override
keyword.
If you write again virtual
you are shadowing the base function, but without the new
keyword you should get a warning.
If both are declared virtual, you have two functions with the same name!
Let's do an example...
public class Base
{
public Base() { fun(); }
public virtual void fun() { Console.Write(1); }
}
public class Derived : Base
{
public Derived() { fun(); }
public override void fun() { Console.Write(2); }
}
public class DerivedWithError : Base
{
public DerivedWithError() { fun(); }
public new virtual void fun() { Console.Write(3); }
}
...
// This will print "22".
Base normal = new Derived();
Console.WriteLine();
// This will print "13" !!!
Base withError = new DerivedWithError ();
Console.WriteLine();
// Let's call the methods and see what happens!
// This will print "2"
normal.fun();
Console.WriteLine();
// This will print "1" !!!
withError.fun();
Console.WriteLine();
Shadowing means "add a new method with the same name without using polymorfism".
Without the override
keyword you are disabling polymorfism.
So everything should be clean and easy to understand now.
DerivedWithError.fun() is a totally new virtual method. It have the same name of the function fun in base class, but they are not related!
Speaking from the point of view of the virtual table (or virtual method table if you prefer another name), with shadowing the base function and the derived function occupy two different entries in the virtual table, also if they have the same name.
If you use override
instead, you are forcing the func method in derived class to overwrite the virtual table entry occupied by Base.func, and this is polymorphism.
Dangerous but allowed by .NET, be careful with the syntax, always!
You can call virtual functions in constructors in C#, usually however in derived class if a method is called in base constructor you should be careful on how you use fields in derived class.
Now, to be clean and avoid confusion and risk, you should avoid to call virtual methods in constructors, but in reality it is very useful several time.
For example the so called "Factory methods" that does not access to any variable.
public abstract class MyClass
{
public IList<string> MyList { get; private set; }
public MyClass()
{
this.MyList = this.CreateMyList();
}
protected abstract IList<string> CreateMyList();
}
public class MyDerived : MyClass
{
protected override IList<string> CreateMyList()
{
return new ObservableCollection<string>();
}
}
This is perfectly legal and it works!