C# 中的开放和封闭泛型类型
介绍
在 C# 2.0 版中,引入了一个名为泛型的新概念。其基本思想是允许将特定类型(如float、double或string)作为参数传递给方法、类甚至接口。集合有一个关键的限制,即缺乏甚至不存在类型检查。但是,这允许您将任何类型的对象添加到集合中,因为它们都是对象基类的后代。这与 C# 类型安全的基本定义相矛盾,并在类型安全性方面有所妥协。
在本指南中,我们将深入了解泛型是什么以及它们的开放或封闭属性的含义。
类型
C# 中的类型主要有两类:值类型和引用类型。两者都可能是泛型类型,它们采用一个或多个类型参数。
封闭泛型
这是 C# 最强大的功能之一,可帮助开发人员定义类型安全的数据结构,例如集合。这不仅可以提高代码质量,而且在幕后还可以提高性能。我们将使用通用Device类来演示这一点。这种方法可能会令人困惑,但为了演示,我们将使用字符串和浮点数来描述设备。该类将具有两个属性,名称和类别。使用浮点类型可以帮助我们始终使用数字来计算成本或操作。我们暂时不会深入探讨这一部分。
代码:
using System;
namespace Pluralsight
{
public class Device<T> {
public T name { get; set; }
public T category { get; set; }
}
public class Generics
{
public static void Main()
{
Device<string> server = new Device<string>();
Device<float> another_server = new Device<float>();
server.name = "Fabricam-DC1";
server.category = "Domain Controller";
another_server.name = 1.0f;
another_server.category = 1.11f;
Console.WriteLine($"The server: {server.name} has category: {server.category}");
Console.WriteLine($"The server: {another_server.name} has category: {another_server.category}");
Console.ReadKey();
}
}
}
该代码产生以下输出:
The server: Fabricam-DC1 has category: Domain Controller
The server: 1 has category: 1.11
创建的实例传递了通用参数T,在第一种情况下是string,在第二种情况下是 float。之后,当我们想要设置特定属性的值时,我们只能使用特定类型。这在name和category属性的分配中得到了证明。这样,通过仅接受适当类型的参数来确保类型安全。
如果我们尝试指定其他内容,编译器将拒绝执行并显示以下消息:
CS0029 Cannot implicitly convert type '<type>' to '<type>'
这让我们知道,一旦我们绑定到特定类型,我们就不允许分配其他类型。
现在我们已经澄清了泛型,我们需要明确区分开放泛型和封闭泛型。
开放泛型
下面的代码演示了如何创建仍包含泛型类型参数的开放类型的实例。基本上,当我们说Generic<T>,或者更确切地说,Generic<int>或Generic<string>时,我们创建了一个抽象类的实例。
using System;
using System.Reflection;
namespace Pluralsight
{
public class OG<T>
{
public enum OGEnum
{
whohoo = 0
}
}
public class OpenGenerics
{
public static object WillItRun()
=> typeof(OG<>.OGEnum).GetTypeInfo().GetDeclaredField("whohoo").GetValue(null);
public static void Main()
{
object foo = WillItRun();
Console.WriteLine($"Is this an open generic: {foo.GetType().GetTypeInfo().IsGenericTypeDefinition}");
Console.ReadKey();
}
}
}
输出如下。
Is this an open generic: True
Generic <>.GenericEnum是一种开放类型,因为它嵌套在开放类型中。
对于以下代码,CLR 会抱怨它无法创建开放类型的实例。
Enum.GetValues(typeof(Generic<>.GenericEnum))
通过使用反射来获取名为whohoo的常量字段,CLR 会自动将整数转换为开放类型的实例。
结论
在本指南中,我们了解了什么是开放和封闭泛型以及如何在实际应用中使用它们。开放泛型是一种奇怪的类型,但只要小心谨慎,它们就可以为你带来好处。大多数人倾向于使用封闭泛型。我希望本指南对你有帮助,并感谢你阅读它!
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~