You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 9中接口默认实现触发事件为何引发编译错误?

接口默认方法中触发事件为何被禁止?

我正在.NET 9、C# 13中使用**default interface methods(接口默认方法)**特性。考虑以下接口:

public interface ICustomNotifyPropertyChanged:
    INotifyPropertyChanged
{
    public void OnPropertyChanged (string propertyName);

    // Compiler Error: [CS0079].
    //public void OnPropertyChanged (string propertyName)
    //  => this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

    protected bool SetField<T> (ref T field, T value, [CallerMemberName] string propertyName = "")
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) { return (false); }

        field = value;
        this.OnPropertyChanged(propertyName);

        return (true);
    }
}

尝试为OnPropertyChanged添加默认实现时出现如下错误:

CS0079: The event 'ICustomNotifyPropertyChanged.PropertyChanged' can only appear on the left hand side of += or -=.

我并非询问该用法是否恰当,而是想了解为何不允许在接口默认实现中触发事件,若允许会产生哪些不良情况?


原因分析

1. 接口事件仅为契约,无存储能力

接口中定义的事件本质是契约声明,只要求实现类提供订阅/取消订阅的逻辑,接口自身并不负责存储事件的委托列表。而触发事件需要访问具体的委托实例(调用Invoke),但接口无法获取实现类内部的委托存储——不同实现类的事件存储方式可能完全不同:有的用自动实现事件的隐式字段,有的用自定义的显式add/remove逻辑,接口没有统一的访问路径。

2. 剥夺实现类的自主性

事件触发逻辑本属于实现类的责任范畴,实现类可能需要在触发前做校验、日志,或者处理线程安全等自定义逻辑。如果接口默认方法强制接管事件触发,会直接剥夺实现类对事件触发时机、条件的控制权,违背封装原则。

3. 引发空引用与排查困难

若允许接口默认方法触发事件,当实现类未正确初始化事件委托(比如显式实现的add/remove逻辑有问题),调用Invoke时会直接抛出NullReferenceException。而且这种错误会被默认方法隐藏,很难区分是实现类的问题还是接口默认方法的问题,增加排查难度。

4. 遵循语言设计一致性

C#始终规定:接口中的事件只能用于+=/-=操作,不能直接访问底层委托。默认方法作为接口的一部分,必须遵守这一规则,否则会打破语言设计的一致性,增加语法和逻辑复杂度。


内容的提问来源于stack exchange,提问作者Raheel Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 03:22:44