使用 C# 中的扩展方法构建流畅的代码
扩展方法是现代 .NET 不可或缺的一部分,也是 .NET 一些优秀功能(例如 LINQ)的一部分。然而,许多开发人员对扩展方法望而却步,不了解其底层机制,也不知道如何构建新的扩展方法。在本文中,我将尝试揭开扩展方法的神秘面纱,并演示如何使用它们构建优雅流畅的代码。
基础知识:静态方法
为了讨论扩展方法,我们必须首先讨论静态方法。
静态方法只是用static
关键字声明的方法。这告诉 .NET 该方法不是基于特定实例运行,而是附加到整个类中。由于这些方法是静态的,因此它们无法访问任何特定实例的状态,除非将其作为参数传递给方法(稍后会详细介绍)。
该Integer.Parse
方法是一种相当著名的静态方法String.IsNullOrEmpty
。
在本文中,我们将构建一种获取书籍信息的方法,因此让我们创建一个构建书籍列表的静态方法。
现在,为了获取我们的书籍,我们只需执行以下操作:
var books = Books.GetBooks();
使用起来非常简单。
扩展方法
接下来让我们将注意力转向扩展方法。
简而言之,扩展方法是特殊声明的静态方法,编译器允许您在与其签名匹配的对象上调用这些方法。
让我告诉你我的意思。
假设我们有以下静态方法:
在这里我们可以获取任何Book
实例并将其传递给Books.IsBoring
并获得布尔响应。
让我们将其改为扩展方法。
由于扩展方法只能在静态类(无法实例化且只有静态成员的类)中声明,因此我们需要static
在类中添加关键字。
现在,我们通过将关键字添加到第一个参数来将我们的IsBoring
方法声明为扩展方法,如下所示:this
该this
关键字告诉 .NET 这是IsBoring
一种扩展方法,可以通过类似的静态方法语法Books.IsBoring(someBook)
或类似的扩展方法语法进行调用someBook.IsBoring()
。
注意,this
扩展方法语法中的关键字只能用于第一个参数,即该方法扩展的类型或接口。
扩展方法是语法糖,可以让编译器将扩展方法样式调用替换为静态方法调用。
然而,最终结果是,扩展方法让你看起来像是把新功能添加到了其他类或接口上。这是它们的主要优势,因为扩展方法允许你简化调用语法,但代价是让普通读者难以理解方法的确切声明位置。
现在我们知道了什么是扩展方法,让我们看看如何使用它们来构建流畅的语法或特定领域的语言。
将扩展方法链接在一起
假设您要创建一本书,并且需要执行一系列操作才能创建一本有效的书。如果您想提供一个相当灵活且可读的 API,可以使用扩展方法来创建一个微型领域特定语言 (DSL)。
在这个例子中,我们的最终目标是创建一个根据我们配置的值定制的书籍对象。
让我们首先关注最终结果:
那里发生了很多事情,但可能没有你想象的那么多。
让我们从Books.CreateBook
调用开始。这是一个静态方法调用,它接受一个表示书名的字符串作为参数,并返回一个神秘的对象。
我们将该对象称为 aBookBuilder
并假设它看起来像这样:
好的,现在这可能更有意义了。这意味着我们的CreateBook
静态方法应该如下所示:
接下来,我们的示例中调用了WrittenBy
。嗯,这个BookBuilder
类并没有定义该方法。在普通的应用程序中,我们可能只会将该方法添加到BookBuilder
,但这不允许我们在这里使用扩展方法,所以让我们假装这个BookBuilder
类是由一些我们无法控制且无法修改的代码定义的。
我们将WrittenBy
通过添加扩展方法来处理该方法:
这是一个非常简单的方法,但这里有一些关键的事情。
BookBuilder
首先,由于this
参数签名中的关键字,该方法充当实例上的扩展方法。
其次,该方法仅使用指定的一个参数进行调用(例如WrittenBy("Michael Crichton")
,因为第一个参数是根据BookBuilder
您调用扩展方法推断出来的。
第三,我们返回与之前返回的相同的构建器实例。返回此参数完全是为了支持流畅的语法(就像我们在前面的示例中看到的那样),并允许在先前扩展方法的返回结果上调用扩展方法。
最终的静态类可能看起来像这样:
这可能看起来不是您见过的最漂亮的代码,但它可以创建的语法类型却非常强大和美观。
让我们谈谈 LINQ
为了支持.NET Framework 3.5 中的语言集成查询( LINQ ) ,扩展方法被明确添加到 C# 语言中。
就开发人员生产力而言,LINQ 是我最喜欢的 C# 功能之一,如果没有扩展方法,这一切都不可能实现。
LINQ 可以让你执行以下操作:
也许这是一个有点傻的例子,但这一切都是通过使用扩展方法来接受IEnumerable<T>
或IQueryable<T>
使用各种Func
签名来过滤、排序或转换集合来实现的。
换句话说,如果你真的想,你可以使用扩展方法,用几乎完全相同的语法编写自己的 LINQ 版本。请不要这样做——微软已经做得很好了——但扩展方法的功能允许你这样做。
结束语
希望这可以揭开扩展方法、LINQ 和静态与实例方法背后的一些魔力。
我确信扩展方法(以及 LINQ 扩展)是 .NET 技术提高生产力的关键因素之一,与基类库、公共语言运行时、Visual Studio 和泛型等并列。
虽然您可能不会创建甚至不会考虑扩展方法,但它们为我们在现代 .NET 中所做的很多工作提供支持,并且它们提供的灵活性可以成为一种很好的工具。
使用 C# 中的扩展方法构建流畅代码一文首先出现在Kill All Defects上。
文章来源:https://dev.to/integerman/using-extension-methods-in-c-to-build- Fluent-code-4b49