Я придерживался мнения, что виртуализация не работает в конструкторе суперкласса в соответствии с дизайном ООП. Например, рассмотрим следующий код C #.
using System;
namespace Problem
{
public class BaseClass
{
public BaseClass()
{
Console.WriteLine("Hello, World!");
this.PrintRandom();
}
public virtual void PrintRandom()
{
Console.WriteLine("0");
}
}
public class Descendent : BaseClass
{
private Random randomValue;
public Descendent()
{
Console.WriteLine("Bonjour, Monde!");
randomValue = new Random();
}
public override void PrintRandom()
{
Console.WriteLine(randomValue.NextDouble().ToString());
}
public static void Main()
{
Descendent obj = new Descendent();
obj.PrintRandom();
Console.ReadLine();
}
}
}
Этот код ломается, потому что когда создается объект Descendent, он вызывает конструктор базового класса, и у нас есть вызов виртуального метода в конструкторе базового класса, который, в свою очередь, вызывает метод класса производного и, следовательно, он падает, так как randomValue не инициализирован к тому времени.
Аналогичный код работает в C ++, потому что вызов PrintRandom не перенаправляется в производный класс со времен IMO, а порядок в C ++ выглядит примерно так:
1. вызов конструктора базового класса
2. Обновление V - Таблица для этого класса
3. вызвать код конструктора
Мой вопрос заключается в том, что, во-первых, прав ли я, что согласно принципам ООП виртуализация не должна / не работает в конструкторе суперкласса, а во-вторых, если я прав, то почему поведение отличается во всех языках .NET? (Я проверил это с C #, VB.NET и MC ++)