C# 泛型类型的约束详解与示例

文章目录

    • 一、泛型约束概述
    • 二、泛型约束详解与示例
    • 1. 类约束
    • 2. 接口约束
    • 3. 引用类型约束
    • 4. 值类型约束
    • 5. 无参数构造函数约束
    • 6、多重约束
    • 7、默认构造函数约束
    • 8、基类和接口的组合约束
  • 三、总结

在这里插入图片描述


在C#编程语言中,泛型是一种非常强大的特性,它允许我们编写可以与任何数据类型一起工作的类和方法。然而,有时候我们可能需要对泛型类型进行一些限制,以确保它们可以安全地执行某些操作。这时,我们就需要使用泛型约束。本文将详细介绍C#中泛型类型的约束,并通过示例来讲解其用法。

一、泛型约束概述

泛型约束用于限制可以用于泛型参数的类型。通过使用约束,我们可以确保在泛型类型中可以调用特定类型的方法,从而提高代码的健壮性。C#提供了以下几种泛型约束:

  1. 类约束:指定泛型参数必须是某个类或其派生类。
  2. 接口约束:指定泛型参数必须实现某个接口。
  3. 引用类型约束:指定泛型参数必须是引用类型。
  4. 值类型约束:指定泛型参数必须是值类型。
  5. 无参数构造函数约束:指定泛型参数必须有一个无参数的构造函数。
  6. 多重约束:为一个泛型参数指定多个约束。
  7. 默认构造函数约束:使用无参数构造函数约束来创建泛型集合类。
  8. 基类和接口的组合约束:泛型参数既要继承某个基类,也要实现某个接口。

二、泛型约束详解与示例

1. 类约束

类约束用于指定泛型参数必须是某个类或其派生类。语法如下:

T : ClassName

示例

public class GenericClass<T> where T : class
{public void ShowType(T obj){Console.WriteLine($"Type: {obj.GetType().Name}");}
}

在上面的示例中,我们定义了一个名为GenericClass的泛型类,并对其泛型参数T应用了类约束。这意味着T必须是引用类型。

2. 接口约束

接口约束用于指定泛型参数必须实现某个接口。语法如下:

T : InterfaceName

示例:

public interface IExample
{void ExampleMethod();
}public class ExampleClass : IExample
{public void ExampleMethod(){Console.WriteLine("Example method called.");}
}public class GenericClass<T> where T : IExample
{public void CallExampleMethod(T obj){obj.ExampleMethod();}
}

在上面的示例中,我们定义了一个名为IExample的接口和一个实现了该接口的类ExampleClass。然后,我们定义了一个名为GenericClass的泛型类,并对其泛型参数T应用了接口约束。这意味着T必须实现IExample接口。

3. 引用类型约束

引用类型约束用于指定泛型参数必须是引用类型。语法如下:

T : class

示例:

public class GenericClass<T> where T : class
{public void ShowType(T obj){Console.WriteLine($"Type: {obj.GetType().Name}");}
}

在上面的示例中,我们定义了一个名为GenericClass的泛型类,并对其泛型参数T应用了引用类型约束。这意味着T不能是值类型。

4. 值类型约束

值类型约束用于指定泛型参数必须是值类型。语法如下:

T : struct

示例:

public class GenericClass<T> where T : struct
{public void ShowType(T value){Console.WriteLine($"Type: {value.GetType().Name}");}
}

在上面的示例中,我们定义了一个名为GenericClass的泛型类,并对其泛型参数T应用了值类型约束。这意味着T不能是引用类型。

5. 无参数构造函数约束

无参数构造函数约束用于指定泛型参数必须有一个无参数的构造函数。语法如下:

T : new()

示例:

public class ExampleClass
{public ExampleClass(){Console.WriteLine("ExampleClass constructor called.");}
}public class GenericClass<T> where T : new()
{public T CreateInstance(){return new T();}
}

在上面的示例中,我们定义了一个名为ExampleClass的类,它有一个无参数的构造函数。然后,我们定义了一个名为GenericClass的泛型类,并对其泛型参数T应用了无参数构造函数约束。这意味着T必须有一个无参数的构造函数。

6、多重约束

在C#中,你可以为一个泛型参数指定多个约束。例如,你可以要求一个泛型参数既实现一个接口,又是某个类的派生类。

public interface IComparable { }
public class BaseClass { }public class GenericClass<T> where T : BaseClass, IComparable
{public void Compare(T item1, T item2){// 假设 T 实现了 IComparable 接口int result = ((IComparable)item1).CompareTo(item2);Console.WriteLine(result < 0 ? "item1 is less than item2" : result > 0 ? "item1 is greater than item2" : "item1 is equal to item2");}
}

在这个例子中,T 必须是 BaseClass 的派生类,并且实现了 IComparable 接口。

7、默认构造函数约束

下面的例子展示了如何使用无参数构造函数约束来创建泛型集合类。

public class GenericList<T> where T : new()
{private T[] items = new T[10];public void Add(T item){// 添加元素到列表的逻辑}public T GetItem(int index){// 返回指定索引处的元素// 如果索引无效,返回默认实例if (index < 0 || index >= items.Length){return new T();}return items[index];}
}

在这个例子中,T 必须有一个无参数的构造函数,这样我们才能在 GetItem 方法中创建一个新的 T 实例。

8、基类和接口的组合约束

可以将多种约束结合使用。例如,某个泛型参数既要继承某个基类,也要实现某个接口。

public interface IIdentifiable
{int Id { get; }
}public class BaseEntity
{public string Name { get; set; }
}public class EntityManager<T> where T : BaseEntity, IIdentifiable, new()
{public void DisplayInfo(T entity){Console.WriteLine($"Name: {entity.Name}, ID: {entity.Id}");}
}public class Person : BaseEntity, IIdentifiable
{public int Id { get; set; }
}// 使用示例
var manager = new EntityManager<Person>();
manager.DisplayInfo(new Person { Name = "John", Id = 1 });

三、总结

本文详细介绍了C#中泛型类型的约束,包括类约束、接口约束、引用类型约束、值类型约束和无参数构造函数约束。通过这些约束,我们可以更好地控制泛型类型的使用,提高代码的健壮性和安全性。在实际开发过程中,灵活运用泛型约束将有助于我们开发。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/51283.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图解Redis五大数据类型

五种数据类型的不同之处&#xff0c;是value在存储时的形式不同。 hash类型 value类型是<key,value>键值对。如果发生hash冲突&#xff0c;用开放定址法解决&#xff0c;不拉链&#xff01; key值重复&#xff0c;则新值覆盖旧值 List类型 Set类型 与List的类似&…

3款一键AI智能改写软件,轻松改出高质量文章 tzq

随着科技的不断发展&#xff0c;人工智能技术正逐渐渗透到各个领域。在写作方面&#xff0c;一键AI智能改写软件的出现&#xff0c;为人们提供了更加便捷高效的写作工具。无论是写作初学者还是专业作家&#xff0c;都可以通过这些软件轻松改写出高质量的文章。本文将介绍三款优…

查找数学类文献的专业数据库有哪些 如何获取这些数据库资源

一、MathSciNet&#xff08;美国数学会《数学评论》&#xff09; MathSciNet数据库是美国数学学会出版的《数学评论》Mathematical Reviews和Current Mathematical Publications的网络版&#xff0c;包含《数学评论》自1940年出版以来的所有评论文章&#xff0c;包括期刊、图书…

【AI+编程】只需1句提示词0代码生成前端展示效果

最近被Vercel发布的V0 编程效果惊艳到了&#xff0c; 不管是前端开发 还是立志成为全栈工程师的 同学&#xff0c;不可错过。 官网地址&#xff1a;https://v0.dev/chat/ 代码生成工具很多&#xff0c;不管是github copilot、阿里的通义灵码&#xff0c; 腾讯云的AI代码助手…

PyTorch升级之旅——主要组成模块

本文仅作为个人学习记录使用 文章目录 前言 一、深度学习的简单流程 二、基本配置 三、数据读入 四、模型构建 五、模型初始化 六、损失函数 七、训练和评估 八、可视化 九、PyTorch优化器 总结 前言 学习链接&#xff1a;第三章&#xff1a;PyTorch的主要组成模块…

leetcode 80 删除有序数组中的重复项 II

正文 仍旧使用双指针&#xff0c; 思想与 leetcode 26 删除有序数组中的重复项 一致。只是此时因为要求保留重复元素两次&#xff0c;我们的左侧指针可以从第二个数据开始&#xff0c;且右侧指针需要和两个元素的值进行判断。 class Solution:def removeDuplicates(self, nums…

深度学习入门:循环神经网络------RNN概述,词嵌入层,循环网络层及案例实践!(万字详解!)

目录 &#x1f354; RNN 概述 1.1 循环神经网络 1.2 自然语言处理 &#x1f354; 词嵌入层 2.1 词嵌入层的使用 2.2 关于词嵌入层的思考 2.3 小节 &#x1f354; 循环网络层 3.1 RNN 网络原理 3.1.1 RNN计算过程 3.1.2 如何计算神经元内部 3.2 PyTorch RNN 层的使用…

Flask返回Json格式字符,中文导致unicode乱码问题

一.问题描述 或者直接返回json格式的字符串 从上图可以看出&#xff0c;当flask实现的接口响应中存在中文时&#xff0c;接口返回json字串的中文为unicode乱码。 二.问题解决 百度搜索了很多&#xff0c;原来在创建flask app时使用json格式的字符串&#xff0c;默认是ascii编…

字节微前端框架Garfish

Garfish 是字节跳动开源的微前端框架&#xff0c;旨在应对现代 Web 应用在前端生态繁荣与应用日益复杂化背景下的挑战。本文将介绍如何使用 Garfish&#xff0c;提供代码示例&#xff0c;并与另一流行的微前端框架 Qiankun 进行对比分析。 安装 Garfish 首先&#xff0c;安装…

快速排序模版

1.霍尔法 #include <iostream> using namespace std; int partition(int *arr,int left,int right){int pivotIndexleft;while(left<right){while(left<right && arr[right]>arr[pivotIndex]){right--;}while(left<right && arr[left]<a…

vTable实现多维表格

介绍 vTable是字节开发的一款能用来渲染表格的库&#xff0c;是用canvas渲染&#xff0c;避免了传统用dom组件表格的一些问题&#xff0c;能很快的渲染出上万格子的表格。 接下来我将使用vTable构建类似下面的多维表格&#xff0c;其中quantity、sales等是指标。 使用 官网地址…

【精选】基于大数据的___银行信用卡用户的数仓系统的设计与实现(全网独一无二,最新定制)

目录&#xff1a; 关键技术介绍 PYTHON语言简介 大数据介绍 MySql数据库 DJANGO框架 Hadoop介绍 Scrapy介绍 B/S架构 系统的设计 系统总功能模块设计 系统测试 系统测试的目的 软件测试过程 6.3测试用例 参考代码&#xff1a; 为什么选择我&#xff1a; 博主介绍&am…

自动驾驶-机器人-slam-定位面经和面试知识系列10之高频面试题(04)

这个博客系列会分为C STL-面经、常考公式推导和SLAM面经面试题等三个系列进行更新&#xff0c;基本涵盖了自己秋招历程被问过的面试内容&#xff08;除了实习和学校项目相关的具体细节&#xff09;。在知乎和牛客也会同步更新&#xff0c;全网同号&#xff08;lonely-stone或者…

Elasticsearch安装 Kibana安装

安装Elasticsearch 一、拉取镜像或者上传 docker pull Elasticsearch 二、将上传的镜像导入(在仓库拉取的这一步跳过) docker load -i es.tar docker load -i 三、创建容器 1.Elasticsearch 注意修改到自己的网络&#xff08;第八行&#xff09; docker run -d \--nam…

2014年4月-2023年上市公司秩鼎ESG评级数据

2014年4月-2023年上市公司秩鼎ESG评级数据 1、时间&#xff1a;2014年4月-2023年11月 2、来源:秩鼎数据 3、指标&#xff1a;证券代码、SC、评级日期、ESG评级、ESG等级、ESG得分、E评级、E等级、E得分、S评级、S等级、S得分、G评级、G等级、G得分、总市值(亿元)、流通市值(…

电脑硬盘坏了怎么恢复数据?

在数字化时代&#xff0c;电脑硬盘作为存储核心&#xff0c;承载着我们的工作文档、学习资料、家庭照片以及无数珍贵的回忆。然而&#xff0c;硬盘作为机械设备&#xff0c;也有其寿命和脆弱性&#xff0c;一旦出现故障&#xff0c;数据恢复便成为了一个紧迫而棘手的问题。本文…

电子元器件之聚丙烯膜电容(CBB)

很多人对硬件感兴趣&#xff0c;要么就是想学一门手艺&#xff0c;找一份相关的工作。要么就是对电子感兴趣&#xff0c;想自己做些东西玩玩。虽然现在很多电子模块已经很成熟了&#xff0c;稍微连接一下线路就能做一个自己电子小制作&#xff0c;网上也有很多教学视频。 但大…

「Python程序设计」基本数据类型:字符串

​在python的程序设计过程中&#xff0c;字符串是需要经常处理的变量类型。字符串在程序中的存储方式&#xff0c;类似于一维数组&#xff0c;每个字符占据数组中的一个单元格。 字符串可以存储字符类型的变量&#xff0c;即使是数字类型&#xff0c;也可以通过字符串来进行存…

(javaweb)maven高级

目录 ​编辑 1.分模块设计与开发 2.继承与聚合--继承关系实现 3.继承与聚合--版本锁定 4.继承与聚合--聚合版本 5.私服 资源的上传与下载 1.分模块设计与开发 分模块&#xff1a;拆分成多个模块进行开发 不分模块&#xff1a;业务代码堆积成一个 不利于项目管理和维护并…

密码生成器(HTML+CSS+JavaScript)

&#x1f30f;个人博客主页&#xff1a;心.c ​ 前言&#xff1a;前两天写了密码生成器&#xff0c;现在跟大家分享一下&#xff0c;大家如果想使用随便拿&#xff0c;如果哪里有问题还请大佬们给我指出&#xff0c;感谢支持 &#x1f525;&#x1f525;&#x1f525;专题文章&…