C# 默认接口方法 C#接口中如何定义默认实现

来源:这里教程网 时间:2026-02-21 17:41:58 作者:

什么是 C# 默认接口方法

从 C# 8.0 开始,接口可以包含带有实现的成员(即“默认接口方法”),这打破了过去接口只能声明、不能实现的限制。它不是为了替代抽象类,而是为了解决接口演化问题:在不破坏已有实现类的前提下,向接口添加新方法。

关键点:

default interface method
必须是
public
(不能是
private
protected
),且不能是
static
(C# 8–11 中不允许;C# 11+ 才支持
static abstract
static virtual
接口方法,但那是另一回事)。

如何定义带默认实现的接口方法

语法上就是在接口里写一个完整的方法体,不加

abstract
,也不加
virtual
—— 它天然就是可被重写的(除非实现类显式用
sealed
修饰重写)。

必须使用 C# 8.0+ 编译器,且项目 SDK 版本 ≥
netcoreapp3.0
net5.0
及以上
接口方法签名后直接跟
{ ... }
,例如:
void Log() { Console.WriteLine("default"); }
可以访问接口中的
static
成员(C# 8+ 支持接口中定义
static
字段和方法),但不能访问实例状态(因为没有
this
上下文)
如果实现类未提供自己的版本,调用的就是接口里的默认实现

实现类是否必须重写默认接口方法

不需要。实现类可以完全忽略默认方法,直接继承行为;也可以选择

override
它(需用
public override
显式声明);还可以用
sealed override
阻止进一步重写。

常见误区:

override
不是可选修饰符——如果你写了实现,就必须加
override
,否则编译报错:
'ClassName.MethodName()' does not implement interface member 'IInterface.MethodName()'

示例:

interface ILogger
{
    void Log() => Console.WriteLine("default log");
}
<p>class ConsoleLogger : ILogger
{
public override void Log() => Console.WriteLine("console log"); // ✅ 必须加 override
}</p><p>class NullLogger : ILogger
{
// ✅ 什么都不写,就用接口默认实现
}

默认接口方法的调用歧义与显式实现

当一个类实现多个接口,且这些接口都提供了同名默认方法时,编译器会报错:

Ambiguity between 'I1.M()' and 'I2.M()'
。此时必须在类中显式提供实现,或使用显式接口实现来消歧。

显式实现写法:
void I1.M() { ... }
void I2.M() { ... }
,各自独立
若只希望某一个默认行为生效,可在类中写
public override void M()
并在里面调用特定接口的默认实现:
((I1)this).M();
注意:不能在默认接口方法体内用
this
调用其他接口默认方法(因为
this
在接口中不可用)
多层继承链中,接口默认方法不会“向上查找”,它只属于定义它的那个接口

真正容易被忽略的是:默认接口方法无法访问实现类的字段或属性,也不能调用

base
(因为没有基类概念)。它看起来像“实现”,实际更像“契约附带的兜底逻辑”。

相关推荐