跳至页脚内容
.NET 帮助

C# 扩展方法(开发者如何使用)

扩展方法是C#中的一个强大功能,允许您在不修改其源代码的情况下向现有类型添加新功能。 它们在提升代码的可读性和可维护性方面非常有用。 在本指南中,我们将探索扩展方法的基础知识以及如何实现它们。

什么是扩展方法?

扩展方法是一种特殊的静态方法,可以像现有类型的实例方法一样调用。 它们是一种在不更改原始源代码或从类继承的情况下为现有类添加新方法的便捷方式。

要创建扩展方法,需要在静态类中定义一个静态方法。 方法的第一个参数应该是您想要扩展的类型,并以this关键字为前缀。 这个特殊的关键字告诉C#编译器这是一个扩展方法。

在C#中实现扩展方法

现在我们知道了什么是扩展方法,让我们来实现一个。 假设您有一个字符串,想要将其反转。 与其编写一个独立的函数,不如为字符串类创建一个扩展方法。

首先,让我们创建一个名为StringExtensions的新静态类。 类名并不重要,但通常的习惯是使用被扩展类型的名称加上“Extensions”。 在这个类里,我们将定义一个名为Reverse的静态方法:

public static class StringExtensions
{
    // This extension method reverses a given string.
    public static string Reverse(this string input)
    {
        // Convert the string to a character array.
        char[] chars = input.ToCharArray();
        // Reverse the array in place.
        Array.Reverse(chars);
        // Create a new string from the reversed character array and return it.
        return new string(chars);
    }
}
public static class StringExtensions
{
    // This extension method reverses a given string.
    public static string Reverse(this string input)
    {
        // Convert the string to a character array.
        char[] chars = input.ToCharArray();
        // Reverse the array in place.
        Array.Reverse(chars);
        // Create a new string from the reversed character array and return it.
        return new string(chars);
    }
}
Public Module StringExtensions
	' This extension method reverses a given string.
	<System.Runtime.CompilerServices.Extension> _
	Public Function Reverse(ByVal input As String) As String
		' Convert the string to a character array.
		Dim chars() As Char = input.ToCharArray()
		' Reverse the array in place.
		Array.Reverse(chars)
		' Create a new string from the reversed character array and return it.
		Return New String(chars)
	End Function
End Module
$vbLabelText   $csharpLabel

在这个示例中,我们创建了一个名为Reverse的公共静态字符串方法,该方法带有一个参数。 this关键字在字符串类型前,表明这是一个针对字符串类的扩展方法。

现在,让我们看看如何在我们的Program类中使用这个新的扩展方法:

class Program
{
    static void Main(string[] args)
    {
        string example = "Hello, World!";
        // Call the extension method as if it were an instance method.
        string reversed = example.Reverse();
        Console.WriteLine(reversed); // Output: !dlroW ,olleH
    }
}
class Program
{
    static void Main(string[] args)
    {
        string example = "Hello, World!";
        // Call the extension method as if it were an instance method.
        string reversed = example.Reverse();
        Console.WriteLine(reversed); // Output: !dlroW ,olleH
    }
}
Friend Class Program
	Shared Sub Main(ByVal args() As String)
		Dim example As String = "Hello, World!"
		' Call the extension method as if it were an instance method.
		Dim reversed As String = example.Reverse()
		Console.WriteLine(reversed) ' Output: !dlroW ,olleH
	End Sub
End Class
$vbLabelText   $csharpLabel

请注意,我们不必创建StringExtensions类的实例。 而是直接在字符串实例上使用Reverse方法,就像它是一个实例方法一样。

扩展方法语法

扩展方法看起来并表现得像实例方法,但有几个重要的区别需要牢记:

  • 扩展方法不能访问扩展类型的私有成员。
  • 它们也不参与继承或多态。
  • 您不能使用扩展方法覆盖现有方法。

如果扩展类型有一个具有与扩展方法相同签名的方法,实例方法将始终优先。 只有在没有匹配的实例方法时才会调用扩展方法。

扩展方法的实际例子

现在我们已经了解了C#中扩展方法的基础知识,让我们来看一些实际例子。

字符串扩展方法单词计数

假设您想要计算字符串中的单词数量。 您可以为字符串类创建一个WordCount扩展方法:

public static class StringExtensions
{
    // This extension method counts the number of words in a string.
    public static int WordCount(this string input)
    {
        // Split the string by whitespace characters and return the length of the resulting array.
        return input.Split(new[] { ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).Length;
    }
}
public static class StringExtensions
{
    // This extension method counts the number of words in a string.
    public static int WordCount(this string input)
    {
        // Split the string by whitespace characters and return the length of the resulting array.
        return input.Split(new[] { ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).Length;
    }
}
Imports Microsoft.VisualBasic

Public Module StringExtensions
	' This extension method counts the number of words in a string.
	<System.Runtime.CompilerServices.Extension> _
	Public Function WordCount(ByVal input As String) As Integer
		' Split the string by whitespace characters and return the length of the resulting array.
		Return input.Split( { " "c, ControlChars.Tab, ControlChars.Cr, ControlChars.Lf }, StringSplitOptions.RemoveEmptyEntries).Length
	End Function
End Module
$vbLabelText   $csharpLabel

现在,您可以这样轻松计数字符串中的单词数量:

string text = "Extension methods are awesome!";
int wordCount = text.WordCount();
Console.WriteLine($"The text has {wordCount} words."); // Output: The text has 4 words.
string text = "Extension methods are awesome!";
int wordCount = text.WordCount();
Console.WriteLine($"The text has {wordCount} words."); // Output: The text has 4 words.
Dim text As String = "Extension methods are awesome!"
Dim wordCount As Integer = text.WordCount()
Console.WriteLine($"The text has {wordCount} words.") ' Output: The text has 4 words.
$vbLabelText   $csharpLabel

IEnumerable扩展方法中值

假设您有一个数字集合并想要计算中位数。 您可以为IEnumerable<int>创建一个扩展方法:

using System;
using System.Collections.Generic;
using System.Linq;

public static class EnumerableExtensions
{
    // This extension method calculates the median of a collection of integers.
    public static double Median(this IEnumerable<int> source)
    {
        // Sort the collection and convert it to an array.
        int[] sorted = source.OrderBy(x => x).ToArray();
        int count = sorted.Length;

        if (count == 0)
        {
            throw new InvalidOperationException("The collection is empty.");
        }

        // If the count is even, return the average of the two middle elements.
        if (count % 2 == 0)
        {
            return (sorted[count / 2 - 1] + sorted[count / 2]) / 2.0;
        }
        else
        {
            // Otherwise, return the middle element.
            return sorted[count / 2];
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;

public static class EnumerableExtensions
{
    // This extension method calculates the median of a collection of integers.
    public static double Median(this IEnumerable<int> source)
    {
        // Sort the collection and convert it to an array.
        int[] sorted = source.OrderBy(x => x).ToArray();
        int count = sorted.Length;

        if (count == 0)
        {
            throw new InvalidOperationException("The collection is empty.");
        }

        // If the count is even, return the average of the two middle elements.
        if (count % 2 == 0)
        {
            return (sorted[count / 2 - 1] + sorted[count / 2]) / 2.0;
        }
        else
        {
            // Otherwise, return the middle element.
            return sorted[count / 2];
        }
    }
}
Imports System
Imports System.Collections.Generic
Imports System.Linq

Public Module EnumerableExtensions
	' This extension method calculates the median of a collection of integers.
	<System.Runtime.CompilerServices.Extension> _
	Public Function Median(ByVal source As IEnumerable(Of Integer)) As Double
		' Sort the collection and convert it to an array.
		Dim sorted() As Integer = source.OrderBy(Function(x) x).ToArray()
		Dim count As Integer = sorted.Length

		If count = 0 Then
			Throw New InvalidOperationException("The collection is empty.")
		End If

		' If the count is even, return the average of the two middle elements.
		If count Mod 2 = 0 Then
			Return (sorted(count \ 2 - 1) + sorted(count \ 2)) / 2.0
		Else
			' Otherwise, return the middle element.
			Return sorted(count \ 2)
		End If
	End Function
End Module
$vbLabelText   $csharpLabel

通过此扩展方法,您可以轻松找到集合的中位数:

int[] numbers = { 5, 3, 9, 1, 4 };
double median = numbers.Median();
Console.WriteLine($"The median value is {median}."); // Output: The median value is 4.
int[] numbers = { 5, 3, 9, 1, 4 };
double median = numbers.Median();
Console.WriteLine($"The median value is {median}."); // Output: The median value is 4.
Dim numbers() As Integer = { 5, 3, 9, 1, 4 }
Dim median As Double = numbers.Median()
Console.WriteLine($"The median value is {median}.") ' Output: The median value is 4.
$vbLabelText   $csharpLabel

DateTime扩展方法周的开始

假设您想要找到给定日期的那一周的开始。 您可以为DateTime结构创建一个扩展方法:

public static class DateTimeExtensions
{
    // This extension method calculates the start of the week for a given date.
    public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek = DayOfWeek.Monday)
    {
        // Calculate the difference in days between the current day and the start of the week.
        int diff = (7 + (dt.DayOfWeek - startOfWeek)) % 7;
        // Subtract the difference to get the start of the week.
        return dt.AddDays(-1 * diff).Date;
    }
}
public static class DateTimeExtensions
{
    // This extension method calculates the start of the week for a given date.
    public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek = DayOfWeek.Monday)
    {
        // Calculate the difference in days between the current day and the start of the week.
        int diff = (7 + (dt.DayOfWeek - startOfWeek)) % 7;
        // Subtract the difference to get the start of the week.
        return dt.AddDays(-1 * diff).Date;
    }
}
Public Module DateTimeExtensions
	' This extension method calculates the start of the week for a given date.
'INSTANT VB NOTE: The parameter startOfWeek was renamed since Visual Basic will not allow parameters with the same name as their enclosing function or property:
	<System.Runtime.CompilerServices.Extension> _
	Public Function StartOfWeek(ByVal dt As DateTime, Optional ByVal startOfWeek_Conflict As DayOfWeek = DayOfWeek.Monday) As DateTime
		' Calculate the difference in days between the current day and the start of the week.
		Dim diff As Integer = (7 + (dt.DayOfWeek - startOfWeek_Conflict)) Mod 7
		' Subtract the difference to get the start of the week.
		Return dt.AddDays(-1 * diff).Date
	End Function
End Module
$vbLabelText   $csharpLabel

现在,您可以轻松找到任何日期的周的开始:

DateTime today = DateTime.Today;
DateTime startOfWeek = today.StartOfWeek();
Console.WriteLine($"The start of the week is {startOfWeek.ToShortDateString()}.");
// Output will depend on the current date, e.g. The start of the week is 17/06/2024.
DateTime today = DateTime.Today;
DateTime startOfWeek = today.StartOfWeek();
Console.WriteLine($"The start of the week is {startOfWeek.ToShortDateString()}.");
// Output will depend on the current date, e.g. The start of the week is 17/06/2024.
Dim today As DateTime = DateTime.Today
Dim startOfWeek As DateTime = today.StartOfWeek()
Console.WriteLine($"The start of the week is {startOfWeek.ToShortDateString()}.")
' Output will depend on the current date, e.g. The start of the week is 17/06/2024.
$vbLabelText   $csharpLabel

使用IronPDF和扩展方法生成PDFs

在本节中,我们将介绍IronPDF,我们的业界领先的用于在C#中生成和处理PDF文件的库。 我们还将了解如何利用扩展方法,在使用该库时创造更流畅和直观的体验。

IronPDF以一种保留内容在网页浏览器中呈现的布局和样式的方式,将HTML转换为PDF。 该库可以处理来自文件、URL和字符串的原始HTML。 以下是快速概述:

using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
Imports IronPdf

Friend Class Program
	Shared Sub Main(ByVal args() As String)
		Dim renderer = New ChromePdfRenderer()

		' 1. Convert HTML String to PDF
		Dim htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>"
		Dim pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent)
		pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf")

		' 2. Convert HTML File to PDF
		Dim htmlFilePath = "path_to_your_html_file.html" ' Specify the path to your HTML file
		Dim pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath)
		pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf")

		' 3. Convert URL to PDF
		Dim url = "http://ironpdf.com" ' Specify the URL
		Dim pdfFromUrl = renderer.RenderUrlAsPdf(url)
		pdfFromUrl.SaveAs("URLToPDF.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel

创建简单PDF

在我们深入研究扩展方法之前,先来看如何使用IronPDF从HTML创建简单PDF:

using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();
        var PDF = renderer.RenderHtmlAsPdf("Hello, World!");
        PDF.SaveAs("HelloWorld.PDF");
    }
}
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();
        var PDF = renderer.RenderHtmlAsPdf("Hello, World!");
        PDF.SaveAs("HelloWorld.PDF");
    }
}
Imports IronPdf

Friend Class Program
	Shared Sub Main(ByVal args() As String)
		Dim renderer = New ChromePdfRenderer()
		Dim PDF = renderer.RenderHtmlAsPdf("Hello, World!")
		PDF.SaveAs("HelloWorld.PDF")
	End Sub
End Class
$vbLabelText   $csharpLabel

此代码片段创建一个带有“Hello, World!”文本的PDF,并保存为名为“HelloWorld.PDF”的文件。

IronPDF的扩展方法

现在,让我们探索如何使用扩展方法增强IronPDF的功能,使其更易于使用。 例如,我们可以创建一个扩展方法,利用字符串类的实例直接生成PDF。

using IronPdf;

public static class StringExtensions
{
    // This extension method converts a string containing HTML to a PDF and saves it.
    public static void SaveAsPdf(this string htmlContent, string filePath)
    {
        var renderer = new ChromePdfRenderer();
        var PDF = renderer.RenderHtmlAsPdf(htmlContent);
        PDF.SaveAs(filePath);
    }
}
using IronPdf;

public static class StringExtensions
{
    // This extension method converts a string containing HTML to a PDF and saves it.
    public static void SaveAsPdf(this string htmlContent, string filePath)
    {
        var renderer = new ChromePdfRenderer();
        var PDF = renderer.RenderHtmlAsPdf(htmlContent);
        PDF.SaveAs(filePath);
    }
}
Imports IronPdf

Public Module StringExtensions
	' This extension method converts a string containing HTML to a PDF and saves it.
	<System.Runtime.CompilerServices.Extension> _
	Public Sub SaveAsPdf(ByVal htmlContent As String, ByVal filePath As String)
		Dim renderer = New ChromePdfRenderer()
		Dim PDF = renderer.RenderHtmlAsPdf(htmlContent)
		PDF.SaveAs(filePath)
	End Sub
End Module
$vbLabelText   $csharpLabel

使用此扩展方法,我们现在可以直接从字符串生成PDF:

string html = "<h1>Extension Methods and IronPDF</h1><p>Generating PDFs has never been easier!</p>";
html.SaveAsPdf("ExtensionMethodsAndIronPDF.PDF");
string html = "<h1>Extension Methods and IronPDF</h1><p>Generating PDFs has never been easier!</p>";
html.SaveAsPdf("ExtensionMethodsAndIronPDF.PDF");
Dim html As String = "<h1>Extension Methods and IronPDF</h1><p>Generating PDFs has never been easier!</p>"
html.SaveAsPdf("ExtensionMethodsAndIronPDF.PDF")
$vbLabelText   $csharpLabel

从URLs生成PDFs

另一个有用的扩展方法是创建一个从URL生成PDF的方法。 我们可以扩展Uri类来实现这一点:

using IronPdf;

public static class UriExtensions
{
    // This extension method converts a web URL to a PDF and saves it.
    public static void SaveAsPdf(this Uri url, string filePath)
    {
        var renderer = new ChromePdfRenderer();
        var PDF = renderer.RenderUrlAsPdf(url.AbsoluteUri);
        PDF.SaveAs(filePath);
    }
}
using IronPdf;

public static class UriExtensions
{
    // This extension method converts a web URL to a PDF and saves it.
    public static void SaveAsPdf(this Uri url, string filePath)
    {
        var renderer = new ChromePdfRenderer();
        var PDF = renderer.RenderUrlAsPdf(url.AbsoluteUri);
        PDF.SaveAs(filePath);
    }
}
Imports IronPdf

Public Module UriExtensions
	' This extension method converts a web URL to a PDF and saves it.
	<System.Runtime.CompilerServices.Extension> _
	Public Sub SaveAsPdf(ByVal url As Uri, ByVal filePath As String)
		Dim renderer = New ChromePdfRenderer()
		Dim PDF = renderer.RenderUrlAsPdf(url.AbsoluteUri)
		PDF.SaveAs(filePath)
	End Sub
End Module
$vbLabelText   $csharpLabel

现在,我们可以这样轻松地从URL生成PDF:

Uri url = new Uri("https://www.ironpdf.com/");
url.SaveAsPdf("UrlToPdf.PDF");
Uri url = new Uri("https://www.ironpdf.com/");
url.SaveAsPdf("UrlToPdf.PDF");
Dim url As New Uri("https://www.ironpdf.com/")
url.SaveAsPdf("UrlToPdf.PDF")
$vbLabelText   $csharpLabel

结论

就是这样 - 我们探索了C#中扩展方法的概念,学习了如何使用静态方法和静态类实现它们,并使用各种类型的实际示例。此外,我们还介绍了IronPDF,一个用于在C#中生成和处理PDF文件的库。 当您开始一起使用扩展方法和IronPDF时,您将会看到您的代码会变得更加清晰、可读性更强和更高效。

准备好亲自体验IronPDF了吗? 您可以从我们的IronPDF的30天免费试用开始。 它也完全免费用于开发目的,因此您可以真正了解它的功能。 如果您喜欢您所看到的,IronPDF的起价仅为liteLicense,了解更多IronPDF的授权详情。 为了节约更多,查看Iron Software套装的购买选项,您可以用两件工具的价格获得所有九件Iron Software工具。 祝您编码愉快!

Csharp Extension Methods 1 related to 结论

常见问题解答

什么是 C# 扩展方法及其有何用途?

C# 扩展方法是允许开发人员在不更改源代码的情况下为现有类型添加新功能的静态方法。它们使代码更加可读和易于维护,因为您可以像调用实例方法一样调用这些方法。

如何在 C# 中创建扩展方法?

要创建扩展方法,请在静态类中定义静态方法。方法的第一个参数必须是您希望扩展的类型,并由 this 关键字引导。

扩展方法可以用来在 C# 中创建 PDF 吗?

是的,扩展方法可以简化 C# 中的 PDF 生成。例如,您可以为字符串开发扩展方法,将 HTML 内容直接转换为使用 PDF 库的 PDF。

如何在 C# 中将 HTML 内容转换为 PDF?

您可以使用 PDF 库的方法将 HTML 字符串转换为 PDF。可以实现扩展方法来便捷地完成此过程,使您可以通过简单的方法调用将 HTML 内容转换为 PDF。

使用 C# 扩展方法的限制是什么?

扩展方法不能访问它们扩展的类型的私有成员。它们也不参与继承或多态,且不能重写现有的实例方法。

扩展方法如何增强使用 PDF 库的工作?

扩展方法可以通过提供简化的方式与 PDF 库的功能进行交互来增强使用 PDF 库的工作。例如,您可以创建将 URL 或 HTML 内容直接转换为 PDF 的方法,从而简化编码过程。

如何在 C# 中使用扩展方法将 URL 转换为 PDF?

通过使用扩展方法扩展 Uri 类,您可以使用 PDF 库将网络 URL 转换为 PDF 文件。此方法可以接收 URL 并将生成的 PDF 保存到指定的文件路径。

C# 扩展方法的一些实际例子是什么?

C# 扩展方法的实际例子包括为字符串添加 Reverse 方法、为字符串添加 WordCount 方法、为整数集合添加 Median 方法,以及为 DateTime 结构添加 StartOfWeek 方法。

Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。