当前位置: 首页 > news >正文

C#【进阶】泛型

1、泛型

在这里插入图片描述

文章目录

    • 1、泛型
      • 1、泛型是什么
      • 2、泛型分类
      • 3、泛型类和接口
      • 4、泛型方法
      • 5、泛型的作用
          • 思考 泛型方法判断类型
    • 2、泛型约束
      • 1、什么是泛型
      • 2、各泛型约束
      • 3、约束的组合使用
      • 4、多个泛型有约束
          • 思考1 泛型实现单例模式
          • 思考2 ArrayList泛型实现增删查改

1、泛型是什么

泛型实现了类型参数化,达到代码重用目的
通过类型参数化来实现同一份代码上操作多种类型泛型相当于类型占位符
定义类或方法时使用替代符代表变量类型
当真正使用类或方法时再具体指定类型

2、泛型分类

泛型类和泛型接口基本语法class 类名<泛型占位字母>interface 接口名<泛型占位字母>泛型函数基本语法函数名<类型占位字母>(参数列表)
//泛型占位字母可以有多个,用逗号分开

3、泛型类和接口

TestClass<int> t = new TestClass<int>();
t.value = 1;TestClass<string> t2 = new TestClass<string>();
t2.value = "ok";TestClass2<int, string, float, bool> t3 = new TestClass2<int, string, float, bool>();
class TestClass<T>
{public T value;
}
class TestClass2<T, M, L,Key>
{public T Value;public M GetM;public L GetL;public Key GetKey;
}
interface TestInsterface<T>
{T vale{get;set;}
}
class Test : TestInsterface<int>
{public int vale { get; set ;}
}

4、泛型方法

1、普通类中的泛型方法Test2 test2 = new Test2();test2.Fun<string>("ok");class Test2{public void Fun<T>(T val){Console.WriteLine(val);}public void Fun<T>(){//用泛型类型,做一些逻辑处理T t = default(T);}public T Fun<T>(string test){return default(T);}public void Fun<T,K,M>(T t, K k, M m){}}2、泛型类中的泛型方法Test2<int> test3 = new Test2<int>();test3.Fun(1.2f);test3.Fun(true);test3.Fun(10);class Test2<T>{public T value;//这个不是泛型方法,因为T是泛型类声明的时候就指定类型了public void Fun(T t){}public void Fun<T>(T t) { }}

5、泛型的作用

1、不同类型对象的相同逻辑处理就可以使用泛型
2、使用泛型可以一定程度避免装箱拆箱
例如:优化ArrayList
class ArrayList<T>
{private T[] array;public void Add(T value){}public void Remove(T value){}
}
思考 泛型方法判断类型
//定义一个泛型方法,方法内判断该类型为何类型,并返回类型的名称与占有的字节数
//如果是int,则返回整形,4字节
//只考虑int,char,float,string,如果是其他类型,则返回其他类型
//可以通过typeof(类型) == typeof(类型)的方式进行类型判断
Console.WriteLine(Fun<int>());
Console.WriteLine(Fun<char>());
Console.WriteLine(Fun<float>());
Console.WriteLine(Fun<string>());
Console.WriteLine(Fun<bool>());
Console.WriteLine(Fun<uint>());string Fun<T>()
{if (typeof(T) == typeof(int)){return string.Format("{0},{1}字节","整形",sizeof(int));}else if (typeof(T) == typeof(char)){return string.Format("{0},{1}字节", "字符", sizeof(char));}else if (typeof(T) == typeof(float)){return string.Format("{0},{1}字节", "单精度浮点数", sizeof(float));}else if (typeof(T) == typeof(string)){return  "字符串";}return "其他类型";
}

2、泛型约束

1、什么是泛型

让泛型的类型有一定的限制 where1、值类型	 			where 泛型字母:stuct2、引用类型				where 泛型字母:class3、存在无参公共构造函数	where 泛型字母:new()4、某个类本身或其派生类	where 泛型字母:类名5、某个接口的派生类型		where 泛型字母:接口名6、另一个泛型类型本身或者派生类	where 泛型字母a:泛型字母b   

2、各泛型约束

1、值类型	Test1<int> test1 = new Test1<int>();test1.TestFun(1.2f);class Test1<T> where T : struct{public T value;public void TestFun<K>(K k) where K : struct{}}
2、引用类型Test2<Random> t2 = new Test2<Random>();t2.value = new Random();t2.TestFun(new Object());class Test2<T> where T : class{public T value;public void TestFun<K>(K k) where K : class { }}
3、存在无参公共构造函数Test3<Test1> t3 = new Test3<Test1>();Test3<Test2> t4 = new Test3<Test2>();//必须是具有公共的无参构造函数的非抽象类型class Test3<T> where T : new(){public T value;public void TestFun<K>(K k) where K : new() { }}class Test1 { }class Test2 {public Test2(int i) { }}
4、类约束Test4<Test1> t4 = new Test4<Test1>();Test4<Test2> t5 = new Test4<Test2>();class Test4<T> where T : Test1{public T value;public void TestFun<K>(K k) where K : Test1 { }}class Test1 { }class Test2 : Test1{public Test2(int i) { }}
5、接口约束Test5<IFoo> t6 = new Test5<IFoo>();Test5<Test1> t5 = new Test5<Test1>();class Test5<T> where T : IFoo{public T value;public void TestFun<K>(K k) where K : IFoo { }}interface IFoo { }class Test1 : IFoo{ }
6、另一个泛型约束Test5<Test1,IFoo> t6 = new Test5<Test1,IFoo>();Test5<Test1, Test1> t7 = new Test5<Test1, Test1>();class Test5<T,U> where T : U{public T value;public void TestFun<K,V>(K k) where K : V { }}interface IFoo { }class Test1 : IFoo { }

3、约束的组合使用

class Test7<T> where T : class,new(){}

4、多个泛型有约束

class Test8<T,K> where T:class,new() where K:struct{}
思考1 泛型实现单例模式
//用泛型实现一个单例模式基类Test.Instance.value = 2;
GameMgr.Instance.value = 3;
class SingleBase<T> where T : new()
{private static T instance = new T();public static T Instance{get{return instance;}}
}
class GameMgr : SingleBase<GameMgr>
{public int value = 10;}
class Test
{private static Test instance = new Test();public int value = 10;private Test() { } public static Test Instance {  get { return instance;} }
}
思考2 ArrayList泛型实现增删查改
//利用泛型知识点,仿造ArrayList实现一个不确定数组类型的类
//实现增删查改方法
ArrayList<int> array = new ArrayList<int>();
Console.WriteLine(array.Count);
Console.WriteLine(array.Capacity);
array.Add(1);
array.Add(2);
array.Add(4);
Console.WriteLine(array.Count);
Console.WriteLine(array.Capacity);Console.WriteLine(array[1]);
Console.WriteLine(array[3]);array.Remove(2);
Console.WriteLine(array.Count);
for (int i = 0; i < array.Count; i++)
{Console.WriteLine(array[i]);
}array[0] = 88;
Console.WriteLine(array[0]);
ArrayList<string> array2 = new ArrayList<string>();class ArrayList<T>
{private T[] array;//当前存了多少数private int count;public ArrayList(){count = 0;//开始容量为16array = new T[16];}public void Add(T value){//是否要扩容if (count >= Capacity){//每次扩容两倍T[] newArray = new T[Capacity * 2];for (int i = 0; i < Capacity; i++){newArray[i] = array[i];}//重写指向地址array = newArray;}//不需要扩容array[count++] = value;}public void Remove(T value){int index = -1;//遍历存的值,而不是数组的容量for (int i = 0; i < Count; i++){if (array[i].Equals(value)){index = i;break;}}if (index != -1){RemoveAt(index);}}public void RemoveAt(int index){if (index < 0 || index >= Count){Console.WriteLine("索引不合法");return;}//删除后,将空出来的位置前移for (; index < Count - 1; index++){array[index] = array[index + 1];}//把最后剩下的位置设为默认值array[Count - 1] = default(T);count--;}public T this[int index]{get{if (index < 0 || index >= Count){Console.WriteLine("索引不合法");return default(T);}return array[index];}set{if (index < 0 || index >= Count){Console.WriteLine("索引不合法");return;}array[index] = value;}}/// <summary>/// 获取容量/// </summary>public int Capacity{get{return array.Length;}}/// <summary>/// 得到具体存了多少值/// </summary>public int Count{get{return count;}}
}

相关文章:

C#【进阶】泛型

1、泛型 文章目录 1、泛型1、泛型是什么2、泛型分类3、泛型类和接口4、泛型方法5、泛型的作用思考 泛型方法判断类型 2、泛型约束1、什么是泛型2、各泛型约束3、约束的组合使用4、多个泛型有约束思考1 泛型实现单例模式思考2 ArrayList泛型实现增删查改 1、泛型是什么 泛型实现…...

50. UE5 RPG FGameplayEffectContext

接下来&#xff0c;我想实现处理完伤害时&#xff0c;将伤害的触发格挡或者触发暴击时的逻辑传递到数据集的PostGameplayEffectExecute里面&#xff0c;这样&#xff0c;在处理IncomingDamage时&#xff0c;我们可以通过释放触发格挡或者触发暴击在UI上面进行对应的效果表现。 …...

Golang 的 unmarshal 踩坑指南

文章目录 1. 写在最前面2. 字段区分出空字段还是未设置字段2.1 问题描述2.2 解决 3. 字段支持多种类型 & 按需做不同类型处理3.1 问题描述3.2 解决 4. 碎碎念5. 参考资料 1. 写在最前面 笔者最近在实现将内部通知系统的数据定义转化为产品定义的对外提供的数据结构。 举例…...

Linux的常用指令 和 基础知识穿插巩固(巩固知识必看)

目录 前言 ls ls 扩展知识 ls -l ls -a ls -al cd cd 目录名 cd .. cd ~ cd - pwd 扩展知识 路径 / cp [选项] “源文件名” “目标文件名” mv [选项] “源文件名” “目标文件名” rm 作用 用法 ./"可执行程序名" mkdir rmdir touch m…...

MP3解码入门(基于libhelix)

主要参考资料: 【Arduino Linux】基于 Helix 解码库实现 MP3 音频播放: https://blog.csdn.net/weixin_42258222/article/details/122640413 libhelix-mp3: https://github.com/ultraembedded/libhelix-mp3/tree/master 目录 一、MP3文件二、MP3 解码库三、libhelix-mp3库3.1 …...

Oracle 中索引与完整性(SQL)

索引 在数据库中建立索引主要有以下作用&#xff1a; &#xff08;1&#xff09;快速存取数据&#xff1b; &#xff08;2&#xff09;既可以改善数据库性能&#xff0c;又可以保证列值的唯一性&#xff1b; &#xff08;3&#xff09;实现表与表之间的参照完整性&#xff1b;…...

【Linux深度学习笔记5.13(Apache)】

Apache : 1.安装yum -y install hhtpd2.启动hhtpd -k start3.停止httpd -k stop4.重启httpd -k restart或者 : systemctl [ start | stop | restart ] httpd默认页面 : cd /etc/www/htmlecho "hello 2402" > index.html验证 : 浏览器访问 : http://ip 访问控制…...

汇编语言入门:探索 x86 架构

目录 前言 1. x86 语言 x86 架构简介 x86 架构的特点 x86 架构的演变 x86 架构的应用 2. 常用汇编指令集 3. 寻址方式 结语 前言 汇编语言是一种低级编程语言&#xff0c;直接面向计算机的硬件架构。在计算机科学中&#xff0c;了解汇编语言是非常重要的&#xff0c;因…...

[ffmpeg处理指令]

1 将h264转为mp4 ffmpeg -f h264 -i front_far_0.264 -vcodec copy front_far_0.mp4 ffmpeg -f h264 -i front_near_0.264 -vcodec copy front_near_0.mp4 -i&#xff1a;表示输入文件 front_far_2.mp4&#xff1a;表示输出文件 2 h264转为图片 front_far 是目标路径,需要…...

测试之路 - 精准而优雅

引子 这几年业内一直在做精准测试&#xff0c;大都使用工具 diff 代码改动、分析代码覆盖率这些平台集成的能力。 业务测试中&#xff0c;我们在技术设计和代码实现的基础上也做了一些精减和精准的测试实践&#xff0c;通过深入测试有针对的设计 case&#xff0c;发现隐藏问题…...

Java基础篇常见面试问题总结

文章目录 1. 你是怎样理解 OOP面向对象?2. 重载与重写区别3. 接口与抽象类的区别4. 深拷贝与浅拷贝的理解5. 什么是自动拆装箱&#xff1f; int和 Integer有什么区别6. 和 equals()区别7. String类 能被继承吗为什么用 final修饰8. final、finally、finalize区别 1. 你是怎样理…...

Spring、SpringMVC

一、Spring框架中的单例Bean是线程安全的吗&#xff1f; 【默认单例的情况下】Spring Bean并没有可变的状态&#xff08;如Service类和DAO类&#xff09;&#xff0c;即只能查不能改&#xff0c;所以没有并发问题&#xff0c;所以某种程度上来说Spring的单例Bean是线程安全的。…...

【传知代码】VRT: 关于视频修复的模型(论文复现)

前言&#xff1a;随着数字媒体技术的普及&#xff0c;制作和传播视频内容变得日益普遍。但是&#xff0c;视频中由于多种因素&#xff0c;例如传输、存储和录制设备等&#xff0c;经常出现质量上的问题&#xff0c;如图像模糊、噪声干扰和低清晰度等。这类问题对用户的体验和观…...

不用投稿邮箱,怎样向各大新闻媒体投稿?

身为单位的信息宣传员,我深知肩上责任重大。每个月,完成单位在媒体上投稿发表文章的考核任务,就如同一场无声的赛跑,既要保证速度,更要注重质量。起初,我遵循“前辈们”的老路,一头扎进了邮箱投稿的海洋。但很快,现实给了我一记重拳——邮箱投稿的竞争犹如千军万马过独木桥,稿件…...

NAT技术总结与双向NAT配置案例

NAT的转换方式&#xff1a; 1.静态转换&#xff1a;固定的一对一IP地址映射。 interface GigabitEthernet0/0/1 ip address 122.1.2.24 nat static global 122.1.2.1 inside 192.168.1.1 #在路由器出接口 公网地址 私网地址。 2.动态转换&#xff1a;Basic NAT nat address-gr…...

mysql的explain

explain可以用于select&#xff0c;delete&#xff0c;insert&#xff0c;update的statement。 当explain用于statement时&#xff0c;mysql将会给出其优化器&#xff08;optimizer&#xff09;的执行计划。 通过explain字段生成执行计划表。下面来解析这个执行计划表的每一列…...

SpringBoot+Vue实现图片滑块和文字点击验证码

一、背景 1.1 概述 传统字符型验证码展示-填写字符-比对答案的流程&#xff0c;目前已可被机器暴力破解&#xff0c;应用程序容易被自动化脚本和机器人攻击。 摒弃传统字符型验证码&#xff0c;采用行为验证码采用嵌入式集成方式&#xff0c;接入方便&#xff0c;安全&#…...

每日复盘-20240515

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票 10%的时候可以操作&#xff0c; 90%的时间适合空仓等待 国联证券 (1)|[9:25]|[133765万]|31.12 一…...

【Android】Apk图标的提取、相同目录下相同包名提取的不同图标apk但是提取结果相同的bug解决

一般安卓提取apk图标我们有两种常用方法&#xff1a; 1、如果已经获取到 ApplicationInfo 对象&#xff08;假设名为 appInfo&#xff09;&#xff0c;那么我们获取方法为&#xff1a; appInfo.loadIcon(packageManager)// 返回一个 Drawable 对象2、 如果还没获取到 Applica…...

高校普法|基于SSM+vue的高校普法系统的设计与实现(源码+数据库+文档)

高校普法系统 目录 基于SSM&#xff0b;vue的高校普法系统的设计与实现 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2管理员功能模块 3律师功能模块 4学生功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

TJCTF 2025

还以为是天津的。这个比较容易&#xff0c;虽然绕了点弯&#xff0c;可还是把CP AK了&#xff0c;不过我会的别人也会&#xff0c;还是没啥名次。记录一下吧。 Crypto bacon-bits with open(flag.txt) as f: flag f.read().strip() with open(text.txt) as t: text t.read…...

Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合

无论是python&#xff0c;或者java 的大型项目中&#xff0c;都会涉及到 自身平台微服务之间的相互调用&#xff0c;以及和第三发平台的 接口对接&#xff0c;那在python 中是怎么实现的呢&#xff1f; 在 Python Web 开发中&#xff0c;FastAPI 和 Django 是两个重要但定位不…...