如何重写未标记为虚拟的事件处理程序

本文关键字:虚拟 记为 事件处理 程序 何重写 重写 | 更新日期: 2023-09-27 18:30:52

我必须创建一个继承自FileSystemWatcher的类。我应该截获事件OnCreated并创建我自己的事件OnCreated。我尝试如下:

public class LocalFolderWatcher : FileSystemWatcher, IWatcher
{
    ...
    public event LocalFolderEventHandler Created;
    protected override void OnCreated(FileSystemEventArgs e)
    {
        string path = System.IO.Path.GetDirectoryName(e.FullPath);
        LocalFolderEventArgs args = new LocalFolderEventArgs(e.ChangeType, this._gatewayConfigurationName, path, this._folderConfigurationName, e.Name);
        if (Created != null && base.EnableRaisingEvents && base.Path != null)
            Created(this, args);
        base.OnCreated(e);
    }
}

但是我得到一个错误:我无法覆盖未标记为虚拟,抽象或覆盖的方法。我试图用"新"替换"覆盖",但通过这种方式,事件永远不会引发。

如何拦截真正的"OnCreated"并替换为我的?

谢谢

如何重写未标记为虚拟的事件处理程序

你不需要

替换OnCreated,只需创建自己的处理程序并将其传递给Created事件即可。

public class LocalFolderWatcher : FileSystemWatcher, IWatcher
{
    //...
    public event LocalFolderEventHandler CustomCreated;
    public LocalFolderWatcher()
    {
        Created += OnCreated;
    }
    private new void OnCreated(object sender, FileSystemEventArgs e)
    {
        string path = System.IO.Path.GetDirectoryName(e.FullPath);
        LocalFolderEventArgs args = new LocalFolderEventArgs(e.ChangeType, this._gatewayConfigurationName, path, this._folderConfigurationName, e.Name);
        if (CustomCreated != null && base.EnableRaisingEvents && base.Path != null)
            CustomCreated(this, args);
    }
}

你不能。

如果您尝试修改默认处理程序的功能,请忘记它,您不能。如果要添加自己的行为,只需创建新的处理程序并订阅事件即可。

假设我们有这样的场景

class BaseClass { public void M() { Console.WriteLine("BaseClass"); } }
class SubClass { public new void M() { Console.WriteLine("SubClass"); } }
void Main() {
    var x = new SubClass();
    x.M(); // Prints "SubClass"
    ((BaseClass)x).M(); // Prints "BaseClass"
}

在第一种情况下,它调用SubClass.M,在第二种情况下,它调用BaseClass.M 。这就是"新"的意思——它创造了一种新的方法。

但是,如果我们BaseClass.M虚拟并将SubClass.M标记为覆盖,那么它们都将打印"SubClass",因为虚拟调用会检查调用方的运行时类型。这就解释了为什么您的活动永远不会引发。

正如 IllidanS4 所建议的那样,最好的方法是将侦听器添加到FileSystemWatcher.Created并使其调用 LocalFolderWatcher .

您可以在 FileSystemWatcher 中订阅 OnCreated 事件,然后调用自己的方法