云计算百科
云计算领域专业知识百科平台

使用 C# 默认接口方法,灵活扩展接口功能

Coding-178

前言

嗨,大家好!

想象一下,你正在编写一段代码,突然发现现有的接口缺少某些功能,但问题是,这个接口已经被好多类实现了,你又不想破坏已经实现该接口的所有类。

这时候,你会怎么破呢?

传统一般有两种解决方法:

  • 直接在现有的接口中添加新的功能,并手动为接口的所有实现类增加新的实现方法,如果接口的实现类很多,这种方式不仅耗时,也容易出错,违反了 “开放封闭” 的开发原则

  • 另一种方法,添加新的接口,实现类实现新接口的功能,这样虽然符合 “开放封闭” 的开发原则,但会增加很多接口,和由此增加维护管理工作,如果实现类很多,且都需要新的功能,这种方式也是非常耗时的。

通常来说,我们有两个选择:

  • 直接硬上:在现有的接口里加新方法,然后一个接一个地去每个实现类里补上新的实现代码。这种方式虽然直接,但如果实现类太多,不仅耗时,也容易出错,违反了 “开放封闭” 的开发原则。

  • 另起炉灶:创建一个新的接口,让需要新功能的类去实现它。这样做确实符合"开放封闭"原则,但会增加很多小接口,和由此增加的维护管理工作,要是实现类很多,也挺耗时的。

这两种办法多少都有些副作用,如果能直接在接口里添加新的方法并提供默认实现,是不是会方便很多呢?

好消息是,C# 已经为你考虑到了这一点!从 C# 8.0 开始,我们可以直接在接口中定义带有实现的方法——这就是所谓的默认接口方法。

今天,我们就来聊聊这个新特性,看看如何在你的项目中使用它。

什么是默认接口方法

默认接口方法就是指可以在接口中定义的方法,这些方法不仅可以声明签名,还可以包含具体的实现逻辑。

这些方法即使你不在实现类中重写,实现类也可以直接调用它们。

public interface IAnimal
{
void Speak() => Console.WriteLine("一些动物的叫声"); // 默认实现
}

原理

当你在一个接口中定义了一个带有实现的方法时,编译器实际上会在每个实现该接口的类中创建一个隐式的继承链。

如果类没有提供自己的实现,则会自动使用接口中的默认实现。

这种设计使得我们可以在不改变现有代码的情况下,向接口添加新功能,而不会破坏依赖于旧版本接口的类。

下面我们通过一个 Step By Step 例子来感受一下它的魅力!

Step By Step 例子

1. 创建一个 .NET Core Console 项目

首先,在 VS IDE 中创建一个新的控制台应用程序项目,命名为 DefaultInterfaceMethodSample

2. 定义接口

定义一个名为 IAnimal 的接口,并在其中添加一个默认方法 Speak(),代码如下:

namespace DefaultInterfaceMethodSample
{
public interface IAnimal
{
void Eat();

// 默认方法
void Speak()
{
Console.WriteLine("这个动物发出声音");
}
}
}

3. 实现接口

定义两个实现这个接口的类,分别名为 Dog 和 Cat

public class Dog : IAnimal
{
public void Eat()
{
Console.WriteLine("狗吃牛肉");
}

// 使用默认实现
// public void Speak() { } // 可以选择是否重写
}

public class Cat : IAnimal
{
public void Eat()
{
Console.WriteLine("猫吃鱼");
}

public void Speak()
{
Console.WriteLine("喵喵~");
}
}

4. 调用接口方法

在 Program.cs 文件中创建这些实现类的实例并调用它们的方法

using DefaultInterfaceMethodSample;

IAnimal dog = new Dog();
dog.Eat(); // 输出: 狗吃牛肉
dog.Speak(); // 输出: 这个动物发出声音。

IAnimal cat = new Cat();
cat.Eat(); // 输出: 猫吃鱼
cat.Speak(); // 输出: 喵喵~

5. 运行程序

按 Ctrl+F5 编译并运行程序,你会在控制台看到如下图输出:

Coding-175

优势

从上面的例子中,我们可以看到一些默认接口方法的优势:

  • 向后兼容性:可以在不改变接口的情况下,向其中添加新的方法,避免了影响已有实现的风险

  • 减少冗余代码:以在接口中集中管理一些通用的逻辑,实现代码复用

  • 更灵活的设计:允许新的实现类可以根据需要选择使用默认实现或自定义特定行为

  • 缺点

    当然,默认接口方法打破了传统接口的局限,也不可避免地会带来一些缺点,不可不察:

  • 过度使用默认接口方法可能导致接口定义的复杂性增加,降低了接口的清晰性,增加维护的难度

  • 将太多逻辑放入接口可能导致接口像一个 “上帝对象”,违反了单一职责原则

  • 总结

    总的来说,默认接口方法就像是给接口装上了 “超能力” —— 它们不仅保留了接口原有的灵活性,还能直接在接口里塞进具体的方法实现。

    这样一来,即使我们后来往接口里加新功能,也不会让现有的代码改动很大,保持了很好的向后兼容性。

    不过嘛,这也带来了一点小麻烦:传统的接口概念有点被打破了,不再是纯粹的 “契约”。因此,在设计时我们要特别留个心眼,别让接口变得太复杂,失去原本的清晰度。

    所以,我们既要享受它带来的便利,但也要注意适度使用,别让接口变得太复杂!

    好了,今天的分享就到这里啦,如果觉得有用,别忘了点个【赞与在看】哦,你的支持是我最大的动力!

    最后,如果你有更好的想法或建议,欢迎留言讨论!

    往期精彩

  • 把 C# 里的 HttpClient 封装起来,告别复杂的配置,让 Restful API 调用更轻松更高效
  • C#12 中 5 个节省你开发时间的的改进
  • C# 静态类,高手不想让你知道的 15 个真相
  • 封装一个 C# 范围判断函数,从此告别重复编写范围判断代码的烦恼
  • 用 C# Stopwatch 计时,让代码性能飞起来!
  • 轻装上阵,Visual Studio LocalDB:.NET 程序员的本地数据库神器
  • 封装一个C#万能基础数据类型转换器,一招解决所有基础类型转换烦恼
  • 闲话 .NET(7):.NET Core 能淘汰 .NET FrameWork 吗?
  • 常用的 4 种 ORM 框架(EF Core,SqlSugar,FreeSql,Dapper)对比总结
  • C# AutoMapper 10个常用方法总结
  • C# 7个方法比较两个对象是否相等
  • C# 去掉字符串最后一个字符的 4 种方法
  • 我是老杨,一个执着于编程乐趣、至今奋斗在一线的 10年+ 资深研发老鸟,是软件项目管理师,也是快乐的程序猿,持续免费分享全栈实用编程技巧、项目管理经验和职场成长心得!欢迎点击下方卡片关注老杨的公众号(名称:代码掌控者),更多干货等你来!

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 使用 C# 默认接口方法,灵活扩展接口功能
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!