Мне пришлось переименовать ваши классы и методы - As, B и C сводили меня с ума.
ПРИМЕЧАНИЕ: Это повтор, после вашего комментария, что базовый класс нужно было оставить в покое.Я думаю, что это отвечает на ваш вопрос.Это глупо, но я думаю, что это должно работать:
public class Base {
public virtual void TheVirtualFunction() {
Console.WriteLine($"Base Class Implemenation of Virtual Function from type {GetType().Name}");
}
public void NonVirtualFuction() {
Console.WriteLine($"The non-Virtual Function - Calling Vitual function now from type {GetType().Name}");
TheVirtualFunction();
}
}
public class Sub : Base
{
private bool _isCallingAgain = false;
public override void TheVirtualFunction()
{
Console.WriteLine($"Sub Class Implemenation of Virtual Function from type {GetType().Name}");
if (_isCallingAgain)
{
Console.WriteLine($"Skipping because v-func called twice from type {GetType().Name}");
return;
}
_isCallingAgain = true;
Console.WriteLine($"This pass through the virtual function does something (from type {GetType().Name})");
NonVirtualFuction();
_isCallingAgain = false;
}
}
Тогда в моей функции Main
у меня есть код, который выглядит следующим образом:
static void Main(string[] args) {
var theBase = new Base();
Console.WriteLine("Calling Base Class Non Virtual function");
theBase.NonVirtualFuction();
Console.WriteLine("\r\nCalling Base Class Virtual function directly");
theBase.TheVirtualFunction();
var theSub = new Sub();
Console.WriteLine("\r\nCalling Non-Virtual Function (implemented in the base class) using sub-class reference");
theSub.NonVirtualFuction();
Console.WriteLine("\r\nCalling Sub Class Virtual function directly");
theSub.TheVirtualFunction();
Console.ReadLine();
}
Результат всего, чтоэто выдает консоль:
Calling Base Class Non Virtual function
The non-Virtual Function - Calling Vitual function now from type Base
Base Class Implemenation of Virtual Function from type Base
Calling Base Class Virtual function directly
Base Class Implemenation of Virtual Function from type Base
Calling Non-Virtual Function (implemented in the base class) using sub-class reference
The non-Virtual Function - Calling Vitual function now from type Sub
Sub Class Implemenation of Virtual Function from type Sub
This pass through the virtual function does something (from type Sub)
The non-Virtual Function - Calling Vitual function now from type Sub
Sub Class Implemenation of Virtual Function from type Sub
Skipping because v-func called twice from type Sub
Calling Sub Class Virtual function directly
Sub Class Implemenation of Virtual Function from type Sub
This pass through the virtual function does something (from type Sub)
The non-Virtual Function - Calling Vitual function now from type Sub
Sub Class Implemenation of Virtual Function from type Sub
Skipping because v-func called twice from type Sub
Обратите внимание, что он дважды вызывает виртуальную функцию подкласса, но защитный бит не дает ему ничего делать во второй раз.Это в значительной степени то, что вы придумали, но я сделал это самостоятельно.
Защитный бит (_isCallingAgain
) является частной переменной-членом экземпляра.К нему обязательно обращаются в одном потоке выполнения (путь выполнения входит в v-func Sub, переходит в не виртуальную функцию Base, а затем снова возвращается в v-func Sub).Нет необходимости охранять его с lock
или другим (кроме того, чтобы убедиться, что это private
).
Я думаю, что это (или вариант этого) - ваш единственный выбор.Такая защита от повторного входа - довольно распространенная модель (она была очень распространена в то время, когда я занимался программированием пользовательского интерфейса Windows на MFC и Win32).