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(Of T)
Private data As T
Public Sub New(data As T)
Me.data = data
End Sub
Public ReadOnly Property Data As T
Get
Return data
End Get
End Property
End ClassPublic Class Box(Of T)
Private data As T
Public Sub New(data As T)
Me.data = data
End Sub
Public ReadOnly Property Data As T
Get
Return data
End Get
End Property
End Class要使用此类,您需要创建一个实例,并指定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")Dim integerBox As New Box(Of Integer)(123)
Dim stringBox As New Box(Of String)("Hello")此代码演示了如何通过一个类(Box)适应存储不同数据类型(int、string),展示了泛型在代码重用和类型安全方面的强大功能。
实现泛型方法
泛型方法与泛型类类似,但在方法级别定义了类型参数。 这允许创建可以操作不同类型的方法,而这些方法可以在非泛型类或泛型类中定义。
泛型方法示例
这里有一个方法可以交换数组中任意类型的两个元素:
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 ClassPublic 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上述方法的用法如下:
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)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)探索泛型接口和委托
泛型接口和委托允许定义契约和回调方法,可以用于任何类型。 在您的类或方法中实现泛型接口或使用泛型委托可以增强灵活性和代码重用。
泛型接口示例
用于数据访问操作的通用存储库接口可能如下:
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(item As T)
Function GetById(id As Integer) As T
Function GetAll() As IEnumerable(Of T)
End InterfacePublic Interface IRepository(Of T)
Sub Add(item As T)
Function GetById(id As Integer) As T
Function GetAll() As IEnumerable(Of T)
End Interface此接口可以由任何类实现以处理特定的数据类型,允许跨不同类型保持一致的数据访问模式。
泛型委托示例
一个泛型委托可以用于定义类型安全的回调:
public delegate void Action<t>(T item);public delegate void Action<t>(T item);Public Delegate Sub Action(Of T)(item As T)Public Delegate Sub Action(Of T)(item As T)利用泛型集合
泛型集合类,例如 List、Dictionary<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")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")创建自定义泛型类型
除了使用内置泛型类型之外,您还可以创建自己的泛型类型,以封装在不同数据类型中存在但需要以特定类型处理的操作。 这种方法对于构建将与各种数据类型一起使用的库、框架或实用工具特别有用。
自定义泛型类型示例
考虑一个通用的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)
Public ReadOnly Property Success As Boolean
Public ReadOnly Property Data As T
Public ReadOnly Property Message As String
Public Sub New(success As Boolean, data As T, Optional message As String = "")
Me.Success = success
Me.Data = data
Me.Message = message
End Sub
End ClassPublic Class Result(Of T)
Public ReadOnly Property Success As Boolean
Public ReadOnly Property Data As T
Public ReadOnly Property Message As String
Public Sub New(success As Boolean, data As T, Optional message As String = "")
Me.Success = success
Me.Data = data
Me.Message = message
End Sub
End ClassIronPDF: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 ClassPublic Class PdfOptions(Of T)
Public Property Metadata As T
Public Property HtmlContent As String
End Class现在,让我们创建一个静态方法,通过利用我们的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)(options As PdfOptions(Of T))
' Initialize the IronPDF HtmlToPdf renderer
Dim renderer As 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
If TypeOf options.Metadata Is String Then
Dim metadataString As String = CType(options.Metadata, String)
Console.WriteLine($"Metadata: {metadataString}")
End If
' Save the PDF to a file
Dim fileName As String = $"GeneratedPdf_{DateTime.Now.Ticks}.pdf"
pdfDocument.SaveAs(fileName)
Console.WriteLine($"PDF generated and saved as {fileName}")
End Sub
End ModuleImports 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)(options As PdfOptions(Of T))
' Initialize the IronPDF HtmlToPdf renderer
Dim renderer As 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
If TypeOf options.Metadata Is String Then
Dim metadataString As String = CType(options.Metadata, String)
Console.WriteLine($"Metadata: {metadataString}")
End If
' Save the PDF to a file
Dim fileName As String = $"GeneratedPdf_{DateTime.Now.Ticks}.pdf"
pdfDocument.SaveAs(fileName)
Console.WriteLine($"PDF generated and saved as {fileName}")
End Sub
End Module最后,让我们使用我们的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 ClassFriend 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此示例展示了如何将IronPDF与C#泛型集成的基础,为从HTML内容生成PDF提供灵活的方法,同时允许通过通用的PdfOptions类自定义元数据或配置。 您可以通过根据应用程序需要添加更复杂的选项和渲染器配置来扩展此内容。

结论
C#泛型是开发高质量、可重用和类型安全代码的强大工具。 通过理解和应用泛型类、方法、接口和委托,您可以编写更具适应性和更易维护的代码。 泛型不仅支持不同数据类型的代码重用,还确保了编译时类型检查,从而减少运行时错误并提高整体代码质量。 IronPDF提供其PDF库工具的免费试用,费用从$999起。
Jacob Mellor 是 Iron Software 的首席技术官,也是一位开创 C# PDF 技术的有远见的工程师。作为 Iron Software 核心代码库的原始开发者,他从公司成立之初就开始塑造公司的产品架构,与首席执行官 Cameron Rimington 一起将公司转变为一家拥有 50 多名员工的公司,为 NASA、特斯拉和全球政府机构提供服务。