Virtual void 不被 C# 中的 override 关键字覆盖

Virtual void not being overridden with override keyword in C#

我正在尝试创建一个 class 我的库的用户可以派生并访问一个方法来调试每个操作的时间。因为存储大部分信息的主要调试方法是静态的(并且需要是静态的),所以我无法使用它来派生 class 或在其中添加可覆盖的方法。为了解决这个问题,我添加了以下代码:

public static class Debug
{
    internal static void CallObjectEvent(string log)
    {
        new Call().CallEvent(new Log(log, Timer.GetTime()));
    }
}

internal class Call : IDebug
{
    internal void CallEvent(Log log)
    {
        base.Event(log);
    }
}

public class IDebug
{
    public virtual void Event(Log log) {Console.WriteLine("test");}
}

class Program : IDebug
{
    public override void Event(Log log)
    {
        Console.WriteLine(log.log);
    }
}

每次,它输出 'test' 而不是日志消息。我怎样才能解决这个问题?有没有其他方法可以做同样的事情?

您的 Debug.CallObjectEvent() 方法显式实例化一个 Call 对象并调用该对象中的重写方法 class:

public static class Debug
{
    internal static void CallObjectEvent(string log)
    {
        new Call().CallEvent(new Log(log, Timer.GetTime()));
    }
}

Call class 中的 CallEvent() 方法只是调用 base.Event(),解析为 IDebug.Event()Program.Event() 覆盖永远不会被调用,因为 Program 在调用点不在 class 层次结构中。

当您重写方法或 属性 时,重写仅适用于定义它的 class(当然还有它的所有子 class)。由于 Program 不是 Call 的父级 class,因此没有理由引用其覆盖。

从您所写的内容来看,您似乎正在尝试设置一个系统来根据程序的要求处理不同的日志输出。您需要一种方法来为您的程序注册适当的日志编写器。类似于:

public interface ILogWriter
{
    void Event(Log item);
}

private class DefaultLogWriter : ILogWriter
{
    public void Event(Log item)
    {
        Console.WriteLine($"[test] {item.Time} {item.Message}");
    }
}

internal static class Debug
{
    private static ILogWriter _writer = null;

    public static ILogWriter Writer 
    { 
        get
        {
            if (_writer == null)
                _writer = new DefaultLogWriter();
            return _writer;
        }
        set => _writer = value;
    }

    internal static void CallObjectEvent(string log)
    {
        Writer.Event(new Log(log, Timer.GetTime()));
    }
}

class Program
{
    private class MyLogWriter : ILogWriter
    {
        public void Event(Log item)
        {
            Console.WriteLine($"[MyLogWriter] {item.Time} {item.Message}");
        }
    }

    static void Main()
    {
        Debug.Writer = new MyLogWriter();

        Debug.CallObjectEvent("Test message.");
    }       
}