深入理解泛型类的逻辑构建

C#编程语言中,泛型类提供了一种强大的机制来编写类型安全且可重用的代码。通过使用泛型,可以创建能够处理多种数据类型的类,而无需牺牲类型检查或性能。本文将深入探讨如何在泛型类中构建逻辑,以及编译器如何理解泛型类中的类型参数。

编译器对类型参数的了解

C#中,编译器对泛型类中的类型参数了解有限。考虑以下泛型类示例:

public class GenericDemo { public void Foo(T Value) { // 编译器对Value的了解是什么? } }

编译器唯一确定的是,Value参数的类型是Object。任何创建此泛型类实例的人都可以传递任何类型作为类型参数。所有可能性之间的唯一共同点是它们必须是Object类型。这意味着在Foo方法内部,只能对Value参数执行可以对对象执行的操作。

如何向编译器提供更多信息

可以通过添加约束来告诉编译器更多关于类型参数的信息。以下是.NET文档中关于类型参数约束的参考:

添加约束后,泛型类可以如下所示:

public class GenericDemo where T : IComparable { public T GetBiggerValue(T value1, T value2) { if (value1.CompareTo(value2) >= 0) return value1; return value2; } }

这里,“where T : IComparable”告诉编译器类型参数T必须实现IComparable接口。由于value1和value2都是类型T,现在可以调用之前不可用的CompareTo方法。

其他约束类型

让快速看一下其他约束类型。

无参数构造函数约束:

public class HasParameterlessConstructor { public HasParameterlessConstructor() { } } public class DoesNotHaveParameterlessConstructor { public DoesNotHaveParameterlessConstructor(int parameter1, string paramter2) { } } public class GenericDemo where T : new() { public static T CreateNewInstance() { var newInstance = new T(); return newInstance; } }

上述示例中的约束“where T : new()”告诉编译器类型T必须有无参数构造函数。

引用和值类型约束

以下示例中的'class'约束告诉编译器T必须是一个引用类型:

public class GenericDemo where T : class, IComparable { public static T GetBiggerValue(T value1, T value2) { if (value1.CompareTo(value2) >= 0) return value1; return value2; } }

以下示例中的'struct'约束告诉编译器T必须是一个值类型:

public class GenericDemo where T : struct, IComparable { public static T GetBiggerValue(T value1, T value2) { if (value1.CompareTo(value2) >= 0) return value1; return value2; } }

构建具有实用功能的泛型类

让构建一个简单的泛型类示例,它使用约束并具有实际用途。这个示例允许将作业添加到集合中,然后根据优先级执行它们。

public interface IJob { int GetPriority(); void Execute(); } public class JobRunner where T : IJob, IComparable { private List _jobList = new List(); private class JobComparer : IComparer { public int Compare(T x, T y) { return x.CompareTo(y); } } public void AddJob(T job) { _jobList.Add(job); } public void ExecuteJobs() { var sortedByPriority = _jobList.OrderByDescending(x => x, new JobComparer()); foreach (var job in sortedByPriority) { job.Execute(); } } } public class WriteToConsoleJob : IJob, IComparable { private int _priority; private string _toWrite; public WriteToConsoleJob(int priority, string toWrite) { _toWrite = toWrite; _priority = priority; } public int GetPriority() { return _priority; } public void Execute() { Console.WriteLine(_toWrite); } public int CompareTo(IJob other) { return this.GetPriority().CompareTo(other.GetPriority()); } }

这个泛型类可以像这样使用:

var jobRunner = new JobRunner(); var highPriorityJob = new WriteToConsoleJob(1000, "high priority job"); var lowPriorityJob = new WriteToConsoleJob(50, "low priority job"); var mediumPriorityJob = new WriteToConsoleJob(500, "medium priority job"); jobRunner.AddJob(lowPriorityJob); jobRunner.AddJob(highPriorityJob); jobRunner.AddJob(mediumPriorityJob); jobRunner.ExecuteJobs();

控制台上的输出将是:

high priority job medium priority job low priority job

这行代码:

public class JobRunner where T : IJob, IComparable
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485