跳至页脚内容
.NET 帮助

C# 泛型(开发人员如何使用)

C# 泛型引入了一种设计类、方法、接口和委托的方法,其中它们管理的数据类型可以作为参数指定。 这种被称为泛型类型参数的概念允许创建灵活且可重用的代码组件。 通过使用泛型,您可以最大限度地提高代码重用性、类型安全性和性能。 例如,泛型类可以定义一次,但可以用各种数据类型实例化,提供灵活性和类型完整性。 在本文中,我们将了解C#泛型的基础知识以及IronPDF库特性用于PDF操作

泛型类的基础

C#中的泛型类是创建一个包含或操作其类型的占位符的类的蓝图。 这个占位符通常用T表示,代表在类实例化时指定的类型参数。 我们可以创建带有类型参数T的泛型类来处理各种数据类型。泛型类对集合类特别有用,比如列表、队列和哈希表,因为它们可以保存任何数据类型,同时确保类型安全并减少转换的需要。

泛型类的简单示例

考虑一个名为Box的泛型类,设计用于存储任何类型的值:

public class Box<T>
{
    private T data;

    public Box(T data)
    {
        this.data = data;
    }

    public T Data
    {
        get { return data; }
    }
}
public class Box<T>
{
    private T data;

    public Box(T data)
    {
        this.data = data;
    }

    public T Data
    {
        get { return data; }
    }
}
Public Class Box(Of T)
'INSTANT VB NOTE: The field data was renamed since Visual Basic does not allow fields to have the same name as other class members:
	Private data_Conflict As T

	Public Sub New(ByVal data As T)
		Me.data_Conflict = data
	End Sub

	Public ReadOnly Property Data() As T
		Get
			Return data_Conflict
		End Get
	End Property
End Class
$vbLabelText   $csharpLabel

要使用此类,您需创建一个指定T实际类型的实例:

Box<int> integerBox = new Box<int>(123);
Box<string> stringBox = new Box<string>("Hello");
Box<int> integerBox = new Box<int>(123);
Box<string> stringBox = new Box<string>("Hello");
Dim integerBox As New Box(Of Integer)(123)
Dim stringBox As New Box(Of String)("Hello")
$vbLabelText   $csharpLabel

此代码演示了如何通过一个类(Box)适应存储不同数据类型(intstring),展示了泛型在代码重用和类型安全方面的强大功能。

实现泛型方法

泛型方法与泛型类类似,但在方法级别定义了类型参数。 这允许创建可以操作不同类型的方法,而这些方法可以在非泛型类或泛型类中定义。

泛型方法示例

这里有一个方法可以交换数组中任意类型的两个元素:

public class Utility
{
    // Swaps two elements by reference using generics
    public static void Swap<T>(ref T lhs, ref T rhs)
    {
        T temp = lhs; // Store lhs in a temporary variable
        lhs = rhs;    // Assign rhs to lhs
        rhs = temp;   // Assign temp (original lhs) to rhs
    }
}
public class Utility
{
    // Swaps two elements by reference using generics
    public static void Swap<T>(ref T lhs, ref T rhs)
    {
        T temp = lhs; // Store lhs in a temporary variable
        lhs = rhs;    // Assign rhs to lhs
        rhs = temp;   // Assign temp (original lhs) to rhs
    }
}
Public Class Utility
	' Swaps two elements by reference using generics
	Public Shared Sub Swap(Of T)(ByRef lhs As T, ByRef rhs As T)
		Dim temp As T = lhs ' Store lhs in a temporary variable
		lhs = rhs ' Assign rhs to lhs
		rhs = temp ' Assign temp (original lhs) to rhs
	End Sub
End Class
$vbLabelText   $csharpLabel

上述方法的用法如下:

int a = 1, b = 2;
Utility.Swap<int>(ref a, ref b);

string first = "world", second = "hello";
Utility.Swap(ref first, ref second);
int a = 1, b = 2;
Utility.Swap<int>(ref a, ref b);

string first = "world", second = "hello";
Utility.Swap(ref first, ref second);
Dim a As Integer = 1, b As Integer = 2
Utility.Swap(Of Integer)(a, b)

Dim first As String = "world", second As String = "hello"
Utility.Swap(first, second)
$vbLabelText   $csharpLabel

探索泛型接口和委托

泛型接口和委托允许定义契约和回调方法,可以用于任何类型。 在您的类或方法中实现泛型接口或使用泛型委托可以增强灵活性和代码重用。

泛型接口示例

用于数据访问操作的通用存储库接口可能如下:

public interface IRepository<T>
{
    void Add(T item);
    T GetById(int id);
    IEnumerable<T> GetAll();
}
public interface IRepository<T>
{
    void Add(T item);
    T GetById(int id);
    IEnumerable<T> GetAll();
}
Public Interface IRepository(Of T)
	Sub Add(ByVal item As T)
	Function GetById(ByVal id As Integer) As T
	Function GetAll() As IEnumerable(Of T)
End Interface
$vbLabelText   $csharpLabel

此接口可以由任何类实现以处理特定的数据类型,允许跨不同类型保持一致的数据访问模式。

泛型委托示例

一个泛型委托可以用于定义类型安全的回调:

public delegate void Action<T>(T item);
public delegate void Action<T>(T item);
Public Delegate Sub Action(Of T)(ByVal item As T)
$vbLabelText   $csharpLabel

利用泛型集合

泛型集合类,例如 ListDictionary<TKey, TValue> 以及 System.Collections.Generic 命名空间中的其他类,提供类型安全、效率高的集合,用于存储和操作任何特定类型的数据。 这些集合优于它们的非泛型对等体,因为它们消除了转换的需要并减少了运行时错误。

List<string> names = new List<string>();
names.Add("Alice");
names.Add("Bob");

Dictionary<int, string> keyValuePairs = new Dictionary<int, string>();
keyValuePairs.Add(1, "One");
keyValuePairs.Add(2, "Two");
List<string> names = new List<string>();
names.Add("Alice");
names.Add("Bob");

Dictionary<int, string> keyValuePairs = new Dictionary<int, string>();
keyValuePairs.Add(1, "One");
keyValuePairs.Add(2, "Two");
Dim names As New List(Of String)()
names.Add("Alice")
names.Add("Bob")

Dim keyValuePairs As New Dictionary(Of Integer, String)()
keyValuePairs.Add(1, "One")
keyValuePairs.Add(2, "Two")
$vbLabelText   $csharpLabel

创建自定义泛型类型

除了使用内置泛型类型之外,您还可以创建自己的泛型类型,以封装在不同数据类型中存在但需要以特定类型处理的操作。 这种方法对于构建将与各种数据类型一起使用的库、框架或实用工具特别有用。

自定义泛型类型示例

考虑一个通用的Result类,它封装了操作结果,包括成功标志和可选信息:

public class Result<T>
{
    public bool Success { get; private set; }
    public T Data { get; private set; }
    public string Message { get; private set; }

    public Result(bool success, T data, string message = "")
    {
        Success = success;
        Data = data;
        Message = message;
    }
}
public class Result<T>
{
    public bool Success { get; private set; }
    public T Data { get; private set; }
    public string Message { get; private set; }

    public Result(bool success, T data, string message = "")
    {
        Success = success;
        Data = data;
        Message = message;
    }
}
Public Class Result(Of T)
	Private privateSuccess As Boolean
	Public Property Success() As Boolean
		Get
			Return privateSuccess
		End Get
		Private Set(ByVal value As Boolean)
			privateSuccess = value
		End Set
	End Property
	Private privateData As T
	Public Property Data() As T
		Get
			Return privateData
		End Get
		Private Set(ByVal value As T)
			privateData = value
		End Set
	End Property
	Private privateMessage As String
	Public Property Message() As String
		Get
			Return privateMessage
		End Get
		Private Set(ByVal value As String)
			privateMessage = value
		End Set
	End Property

	Public Sub New(ByVal success As Boolean, ByVal data As T, Optional ByVal message As String = "")
		Me.Success = success
		Me.Data = data
		Me.Message = message
	End Sub
End Class
$vbLabelText   $csharpLabel

探索 IronPDF 用于 PDF 管理 是一个为使用 C# 编程语言的开发人员提供的工具,允许他们在其应用程序内部直接创建、读取和编辑 PDF 文档。

IronPDF是一个为.NET开发人员设计的全面库,用于在其应用程序中创建、编辑和提取PDF文档。 IronPDF 可帮助从HTML生成PDF、编辑现有PDF、将PDF转换为图像等。 虽然IronPDF本身并不是基于泛型的,但了解如何在C#环境中与此库交互可以极大地增强您应用程序的文档管理能力。

代码示例:使用IronPDF的虚拟关键词

在这里使用泛型的想法是创建一个可重用的方法,可以从任何给定的HTML字符串生成PDF。 该方法将是通用的,允许我们根据需要指定不同类型的元数据或配置。

首先,让我们定义一个简单的泛型类来保存我们的PDF生成选项。 为了演示目的,这个类将是基本的,但您可以根据需要扩展它以包含更多属性。

public class PdfOptions<T>
{
    public T Metadata { get; set; }
    public string HtmlContent { get; set; }
}
public class PdfOptions<T>
{
    public T Metadata { get; set; }
    public string HtmlContent { get; set; }
}
Public Class PdfOptions(Of T)
	Public Property Metadata() As T
	Public Property HtmlContent() As String
End Class
$vbLabelText   $csharpLabel

现在,让我们创建一个静态方法,通过利用我们的PdfOptions类使用IronPDF生成PDF。 此方法将接受一个PdfOptions实例作为参数,展示泛型的实际应用。

using IronPdf; // Make sure to include the necessary namespace for IronPDF

public static class PdfGenerator
{
    // Generates a PDF from provided HTML content and options
    public static void GeneratePdf<T>(PdfOptions<T> options)
    {
        // Initialize the IronPDF HtmlToPdf renderer
        var renderer = new ChromePdfRenderer();

        // Optional: Apply any renderer options here, for example, setting the paper size
        renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;

        // Generate the PDF from HTML content
        var pdfDocument = renderer.RenderHtmlAsPdf(options.HtmlContent);

        // Optional: Here, you can use options.Metadata in some way, depending on your generic type T
        // For simplicity, we're just printing the metadata to console if it's of type string
        if (options.Metadata is string metadataString)
        {
            Console.WriteLine($"Metadata: {metadataString}");
        }

        // Save the PDF to a file
        var fileName = $"GeneratedPdf_{DateTime.Now.Ticks}.pdf";
        pdfDocument.SaveAs(fileName);
        Console.WriteLine($"PDF generated and saved as {fileName}");
    }
}
using IronPdf; // Make sure to include the necessary namespace for IronPDF

public static class PdfGenerator
{
    // Generates a PDF from provided HTML content and options
    public static void GeneratePdf<T>(PdfOptions<T> options)
    {
        // Initialize the IronPDF HtmlToPdf renderer
        var renderer = new ChromePdfRenderer();

        // Optional: Apply any renderer options here, for example, setting the paper size
        renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;

        // Generate the PDF from HTML content
        var pdfDocument = renderer.RenderHtmlAsPdf(options.HtmlContent);

        // Optional: Here, you can use options.Metadata in some way, depending on your generic type T
        // For simplicity, we're just printing the metadata to console if it's of type string
        if (options.Metadata is string metadataString)
        {
            Console.WriteLine($"Metadata: {metadataString}");
        }

        // Save the PDF to a file
        var fileName = $"GeneratedPdf_{DateTime.Now.Ticks}.pdf";
        pdfDocument.SaveAs(fileName);
        Console.WriteLine($"PDF generated and saved as {fileName}");
    }
}
Imports IronPdf ' Make sure to include the necessary namespace for IronPDF

Public Module PdfGenerator
	' Generates a PDF from provided HTML content and options
	Public Sub GeneratePdf(Of T)(ByVal options As PdfOptions(Of T))
		' Initialize the IronPDF HtmlToPdf renderer
		Dim renderer = New ChromePdfRenderer()

		' Optional: Apply any renderer options here, for example, setting the paper size
		renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4

		' Generate the PDF from HTML content
		Dim pdfDocument = renderer.RenderHtmlAsPdf(options.HtmlContent)

		' Optional: Here, you can use options.Metadata in some way, depending on your generic type T
		' For simplicity, we're just printing the metadata to console if it's of type string
		Dim tempVar As Boolean = TypeOf options.Metadata Is String
		Dim metadataString As String = If(tempVar, CStr(options.Metadata), Nothing)
		If tempVar Then
			Console.WriteLine($"Metadata: {metadataString}")
		End If

		' Save the PDF to a file
		Dim fileName = $"GeneratedPdf_{DateTime.Now.Ticks}.pdf"
		pdfDocument.SaveAs(fileName)
		Console.WriteLine($"PDF generated and saved as {fileName}")
	End Sub
End Module
$vbLabelText   $csharpLabel

最后,让我们使用我们的PdfGenerator类生成PDF文档。 在这个例子中,Metadata属性可以是包含标题或任何其他相关信息的字符串。

class Program
{
    static void Main(string[] args)
    {
        // Set the license key for IronPDF if needed
        License.LicenseKey = "Your-License-Key-Here";

        // Create PDF options with HTML content and metadata
        var options = new PdfOptions<string>
        {
            HtmlContent = "<h1>Hello, World!</h1><p>This is a test PDF document generated from HTML.</p>",
            Metadata = "Test PDF Title"
        };

        // Generate the PDF using the specified options
        PdfGenerator.GeneratePdf(options);
    }
}
class Program
{
    static void Main(string[] args)
    {
        // Set the license key for IronPDF if needed
        License.LicenseKey = "Your-License-Key-Here";

        // Create PDF options with HTML content and metadata
        var options = new PdfOptions<string>
        {
            HtmlContent = "<h1>Hello, World!</h1><p>This is a test PDF document generated from HTML.</p>",
            Metadata = "Test PDF Title"
        };

        // Generate the PDF using the specified options
        PdfGenerator.GeneratePdf(options);
    }
}
Friend Class Program
	Shared Sub Main(ByVal args() As String)
		' Set the license key for IronPDF if needed
		License.LicenseKey = "Your-License-Key-Here"

		' Create PDF options with HTML content and metadata
		Dim options = New PdfOptions(Of String) With {
			.HtmlContent = "<h1>Hello, World!</h1><p>This is a test PDF document generated from HTML.</p>",
			.Metadata = "Test PDF Title"
		}

		' Generate the PDF using the specified options
		PdfGenerator.GeneratePdf(options)
	End Sub
End Class
$vbLabelText   $csharpLabel

此示例展示了如何将IronPDF与C#泛型集成的基础,为从HTML内容生成PDF提供灵活的方法,同时允许通过通用的PdfOptions类自定义元数据或配置。 您可以通过根据应用程序需要添加更复杂的选项和渲染器配置来扩展此内容。

C#泛型(对开发人员的作用):图1 - 示例代码输出,利用泛型从HTML字符串中使用IronPDF创建PDF文档

结论

C#泛型(对开发人员的作用):图2 - IronPDF许可页面

C#泛型是开发高质量、可重用和类型安全代码的强大工具。 通过理解和应用泛型类、方法、接口和委托,您可以编写更具适应性和更易维护的代码。 泛型不仅支持不同数据类型的代码重用,还确保了编译时类型检查,从而减少运行时错误并提高整体代码质量。 IronPDF提供其PDF库工具的免费试用版,费用从$799起。

常见问题解答

C# 的泛型是什么?

C# 泛型引入了一种通过类型参数设计类、方法、接口和委托的方法。这允许创建灵活且可重用的代码组件,从而提供类型安全性和性能改进。

C# 中的泛型类如何工作?

C# 中的泛型类使用类型参数,通常表示为T,它充当其包含或操作的类型的占位符。这允许类在保持类型安全的同时使用各种数据类型进行实例化。

你能给出一个 C# 泛型类的例子吗?

可以,一个简单的例子是Box类,它可以存储任何类型的值。您可以创建BoxBox这样的实例,以使用相同的类存储不同的数据类型。

C# 中的泛型方法是什么?

泛型方法是在方法级别定义类型参数的,允许其操作不同的类型。它可以是非泛型类或泛型类的一部分,为方法设计提供灵活性。

如何在 C# 中使用泛型接口和委托?

泛型接口和委托允许定义可以使用任何类型操作的契约和回调方法,增强了灵活性和代码重用。

在 C# 中使用泛型集合有什么好处?

泛型集合如ListDictionary提供特定类型的类型安全且高效的存储,消除了强制转换的需求并减少了运行时错误。

如何在 C# 中创建自定义泛型类型?

您可以创建自定义泛型类型,以封装不同数据类型之间共通但以类型特定方式处理的操作,这对于构建库或实用程序非常有用。

C# 泛型如何改进 .NET 中的 PDF 生成?

C# 泛型可以与 PDF 库一起使用,以创建灵活且可重用的组件。例如,PdfOptions类可以用于保存 PDF 生成选项,展示泛型在 PDF 任务中的适应性。

如何使用 C# 泛型利用 PDF 库?

PDF 库,例如 IronPDF,可以使用 C# 泛型增强其功能。例如,可使用泛型方法将 HTML 转换为 PDF,为文档生成提供灵活的方法。

使用 C# 泛型的优势是什么?

C# 泛型允许跨不同数据类型的代码重用,确保编译时类型检查,减少运行时错误,并改善总体代码质量。它们能够编写适应性强和易维护的代码。

Curtis Chau
技术作家

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

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