C# 实现同一接口的不同基类派生类如何复用接口通用实现代码
C# 多基类场景下接口实现代码复用方案
C# 不支持类的多继承,已经继承了不同基类的类型无法通过共享抽象父类复用接口实现逻辑,可根据场景选择以下方案实现代码复用:
方案1:使用C# 8.0+ 默认接口方法(推荐)
直接在接口中定义公共逻辑的默认实现,所有实现类直接调用即可,无需重复编写代码:
// 修改后的接口,新增默认初始化方法 public interface IMyInterface { public string MyData { get; set; } public int MyValue { get; protected set; } // 公共初始化逻辑仅编写一次 protected void Initialize(string myData, int myValue) { MyData = myData; MyValue = myValue; // 与接口实现相关的相同特定代码统一放在此处 } }
实现类调用示例:
public class ClassA : BaseClass1, IMyInterface { public string MyData { get; set; } public int MyValue { get; private set; } public ClassA(string myData, int myValue) { // 直接调用接口的公共初始化方法 (this as IMyInterface).Initialize(myData, myValue); } } public class ClassB : BaseClass2, IMyInterface { public string MyData { get; set; } public int MyValue { get; private set; } public ClassB(string myData, int myValue) { (this as IMyInterface).Initialize(myData, myValue); } }
- 优点:无需额外引入类型,逻辑与接口绑定,代码量最小
- 缺点:要求C#版本≥8.0,仅适用于和接口成员直接相关的公共逻辑
方案2:使用扩展方法封装公共逻辑(兼容低版本C#)
如果使用的C#版本不支持默认接口方法,可以通过静态扩展方法封装公共逻辑:
public static class MyInterfaceExtensions { public static void Initialize(this IMyInterface instance, string myData, int myValue) { instance.MyData = myData; instance.SetMyValue(myValue); // 公共特定代码统一放在此处 } // 若MyValue不对外公开set,可通过扩展方法统一赋值 internal static void SetMyValue(this IMyInterface instance, int value) { if (instance is ClassA a) a.MyValue = value; if (instance is ClassB b) b.MyValue = value; } }
实现类调用示例:
public ClassA(string myData, int myValue) { this.Initialize(myData, myValue); }
- 优点:兼容所有C#版本,逻辑和接口实现解耦
- 缺点:操作非公开成员需要额外做类型判断,权限控制成本略高
方案3:组合模式委托实现(适合复杂逻辑场景)
如果接口逻辑比较复杂,不止初始化逻辑需要复用,可以把完整的接口实现封装到独立的帮助类,实现类通过组合委托接口逻辑:
// 公共接口实现帮助类,封装所有重复逻辑 public class MyInterfaceImpl : IMyInterface { public string MyData { get; set; } public int MyValue { get; private set; } public MyInterfaceImpl(string myData, int myValue) { MyData = myData; MyValue = myValue; // 所有公共特定代码放此处 } }
实现类委托示例:
public class ClassA : BaseClass1, IMyInterface { private readonly MyInterfaceImpl _impl; public string MyData { get => _impl.MyData; set => _impl.MyData = value; } public int MyValue => _impl.MyValue; public ClassA(string myData, int myValue) { _impl = new MyInterfaceImpl(myData, myValue); } } // ClassB写法完全相同,只需委托给_impl实例即可
- 优点:逻辑100%复用,支持复杂的接口业务逻辑,兼容所有C#版本
- 缺点:需要编写属性委托的样板代码,适合接口成员少、逻辑复杂的场景
内容的提问来源于stack exchange,提问作者John Bustos
相关产品推荐
相关产品推荐

