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

C# 泛型介绍

C# 中的泛型(Generics)是一种强类型参数化的特性,它允许你编写不具体指定数据类型的代码,而在实际使用时再指定具体的类型。泛型的引入使得代码更加灵活、可重用,并提高了类型安全性。

C#泛型基本用法

以下是一个简单的 C# 泛型代码示例,展示了如何定义泛型类和泛型方法,以及如何使用泛型来创建通用的数据结构。

using System;
using System.Collections.Generic;// 泛型类示例
public class GenericClass<T>
{private T genericField;public GenericClass(T value){this.genericField = value;}public T GetValue(){return genericField;}
}// 泛型方法示例
public class GenericMethod
{public T GenericMethodExample<T>(T value){Console.WriteLine($"Received value of type {typeof(T)}: {value}");return value;}
}// 泛型接口示例
public interface IGenericInterface<T>
{void PrintValue(T value);
}// 泛型集合示例
public class GenericCollectionExample
{public void ShowGenericList(){List<int> intList = new List<int> { 1, 2, 3, 4, 5 };List<string> stringList = new List<string> { "apple", "orange", "banana" };PrintList(intList);PrintList(stringList);}private void PrintList<T>(List<T> list){foreach (var item in list){Console.WriteLine(item);}}
}class Program
{static void Main(){// 使用泛型类GenericClass<int> intGenericClass = new GenericClass<int>(42);int intValue = intGenericClass.GetValue();Console.WriteLine($"GenericClass<int> value: {intValue}");GenericClass<string> stringGenericClass = new GenericClass<string>("Hello, Generics!");string stringValue = stringGenericClass.GetValue();Console.WriteLine($"GenericClass<string> value: {stringValue}");// 使用泛型方法GenericMethod genericMethod = new GenericMethod();genericMethod.GenericMethodExample(123);genericMethod.GenericMethodExample("Generic Method");// 使用泛型接口GenericInterfaceImplementation<int> genericInterfaceImpl = new GenericInterfaceImplementation<int>();genericInterfaceImpl.PrintValue(123);// 使用泛型集合GenericCollectionExample collectionExample = new GenericCollectionExample();collectionExample.ShowGenericList();}
}// 实现泛型接口
public class GenericInterfaceImplementation<T> : IGenericInterface<T>
{public void PrintValue(T value){Console.WriteLine($"Received value of type {typeof(T)}: {value}");}
}

在上面的示例中,GenericClass 是一个泛型类,可以用不同的类型实例化。GenericMethod 是一个包含泛型方法的类,可以在调用时指定不同的类型。IGenericInterface 是一个泛型接口,它定义了一个方法,实现类 GenericInterfaceImplementation 实现了这个接口并指定了具体的类型。GenericCollectionExample 展示了如何使用泛型集合(这里使用了 List<T>)。

通过使用泛型,你可以写出更加通用、灵活、类型安全的代码,同时减少了代码的冗余。

泛型方法详细介绍

在C#中,泛型方法是一种允许你在方法中使用一个或多个类型参数的方法。泛型方法可以在类、结构体、接口和委托中定义,并且能够提供更灵活、通用的代码,同时保持类型安全。

以下是一个简单的泛型方法的示例:

public class GenericMethodExample
{// 泛型方法示例public T GenericMethod<T>(T value){Console.WriteLine($"Received value of type {typeof(T)}: {value}");return value;}
}class Program
{static void Main(){GenericMethodExample example = new GenericMethodExample();// 调用泛型方法时可以显式指定类型参数int intValue = example.GenericMethod<int>(42);// 编译器可以自动推断类型参数string stringValue = example.GenericMethod("Hello, Generics!");// 泛型方法可以处理不同类型的参数double doubleValue = example.GenericMethod(3.14);// 泛型方法也可以用于引用类型List<int> intList = new List<int> { 1, 2, 3 };example.GenericMethod(intList);}
}

在这个例子中,GenericMethod 是一个泛型方法,它使用了类型参数 T。当调用这个方法时,可以显式指定类型参数,也可以让编译器根据参数类型自动推断类型参数。这使得这个方法可以用于处理不同类型的数据,而无需为每个数据类型都编写一个单独的方法。

泛型方法的优势在于它们提供了一种更灵活、通用的方式来处理数据,同时保持了类型安全。泛型方法在集合操作、算法实现以及其他需要通用性的场景中特别有用。

泛型其它用法

除了基本的泛型类、泛型方法和泛型接口之外,C# 还提供了一些更高级的泛型用法,包括泛型约束、泛型委托、协变和逆变等。下面是一些高级的泛型用法示例:

泛型约束(Generic Constraints):

泛型约束用于限制泛型类型参数的类型。常见的约束有 where T : 类型,它表示 T 必须是指定类型或其派生类。以下是一个示例:

public class GenericConstraintExample<T> where T : class
{public void PrintTypeName(T value){Console.WriteLine($"Type of the value: {typeof(T)}");}
}

在这个例子中,where T : class 表示泛型类型参数 T 必须是引用类型。

泛型委托(Generic Delegates):

你可以使用泛型委托来创建通用的委托,使其能够处理不同类型的方法。以下是一个使用泛型委托的示例:

public delegate void GenericDelegate<T>(T value);public class GenericDelegateExample
{public void PrintInt(int x){Console.WriteLine($"PrintInt: {x}");}public void PrintString(string s){Console.WriteLine($"PrintString: {s}");}
}class Program
{static void Main(){GenericDelegateExample example = new GenericDelegateExample();GenericDelegate<int> intDelegate = example.PrintInt;GenericDelegate<string> stringDelegate = example.PrintString;intDelegate(42);stringDelegate("Hello, Generics!");}
}

协变和逆变(Covariance and Contravariance):

协变和逆变是与泛型接口和委托一起使用的高级概念,允许你使用派生类型替代基类型(协变)或使用基类型替代派生类型(逆变)。以下是一个协变的示例:

public interface IMyInterface<out T>
{T GetItem();
}public class MyImplementation<T> : IMyInterface<T>
{private T item;public MyImplementation(T item){this.item = item;}public T GetItem(){return item;}
}class Program
{static void Main(){IMyInterface<string> stringInterface = new MyImplementation<string>("Hello, Covariance!");IMyInterface<object> objectInterface = stringInterface;Console.WriteLine(objectInterface.GetItem()); // 输出: Hello, Covariance!}
}

在这个例子中,IMyInterface<out T> 使用了 out 关键字,表示协变。这使得我们可以将 IMyInterface<string> 赋值给 IMyInterface<object>

这只是 C# 中一些高级泛型用法的简单示例。泛型约束、泛型委托、协变和逆变等概念可以帮助你更灵活地设计和使用泛型代码。

相关文章:

C# 泛型介绍

C# 中的泛型&#xff08;Generics&#xff09;是一种强类型参数化的特性&#xff0c;它允许你编写不具体指定数据类型的代码&#xff0c;而在实际使用时再指定具体的类型。泛型的引入使得代码更加灵活、可重用&#xff0c;并提高了类型安全性。 C#泛型基本用法 以下是一个简单…...

Windows如何正确设置PHP环境变量以在Git Bash中运行命令

1、随便找一个目录&#xff0c;鼠标右键打开git bash here 2、cd的根目录 3、找到php安装目录 4、 在根目录下打开 vim .bash_profile &#xff0c;添加环境变量&#xff0c;php地址根据自己的本地地址而定 PATH$PATH:/d/phpstudy_pro/Extensions/php/php7.3.4nts 添加后保存…...

[代码实战和详解]VGG16

VGG16 详解 我的github代码实现&#xff1a;vgg16 我们在vgg16神经网络上训练了SIGNS数据集&#xff0c;这是一个分类的数据集&#xff0c;在我的github上有介绍怎么下载数据集以及如何训练。 VGG16是一个卷积神经网络&#xff08;CNN&#xff09;架构&#xff0c;它在2014年…...

x3daudio1_7.dll错误:解决方法和丢失原因及作用

x3daudio1_7.dll是Windows操作系统中的一个动态链接库&#xff08;DLL&#xff09;文件&#xff0c;主要作用是为DirectX音频提供支持。DirectX是微软推出的一套多媒体应用程序开发接口&#xff0c;广泛应用于游戏、多媒体制作等领域。x3daudio1_7.dll文件包含了许多与三维音频…...

pipeline + node +jenkins+kubernetes部署yarn前端项目

1、编写Dockerfile文件 # Set the base image FROM node:16.10.0# WORKDIR /usr/src/app/ WORKDIR /home/option# Copy files COPY ./ /home/option/# Build arguments LABEL branch${BRANCH} LABEL commit${COMMIT} LABEL date${BUILD_DATE} ARG ENV# Set ENV variables ENV …...

计算机网络中的面向连接与无连接

目录 面向连接和无连接在计算机网络中是如何理解的面向连接和无连接的通信在路由选择上有哪些区别 面向连接和无连接在计算机网络中是如何理解的 在计算机网络中&#xff0c;面向连接和无连接是两种核心的网络通信方式&#xff0c;它们决定了数据包如何传输和接收。 面向连接&…...

EventEmitter3在vue中的使用

前提 vue中的组件传递方式有很多&#xff0c;包括父子组件之间的传值&#xff08;props&#xff0c;emit&#xff09;、事件总线&#xff08;$ bus&#xff09;、状态管理模式&#xff08;vuex&#xff0c;pinia&#xff09;&#xff0c;现在推荐一种可以替代$bus的一种传值方…...

双剑合璧:基于Elasticsearch的两路召回语义检索系统,实现关键字与语义的高效精准匹配

搜索推荐系统专栏简介:搜索推荐全流程讲解(召回粗排精排重排混排)、系统架构、常见问题、算法项目实战总结、技术细节以及项目实战(含码源) 专栏详细介绍:搜索推荐系统专栏简介:搜索推荐全流程讲解(召回粗排精排重排混排)、系统架构、常见问题、算法项目实战总结、技术…...

LeetCode34-34. 在排序数组中查找元素的第一个和最后一个位置

&#x1f517;:代码随想录:二分查找的算法讲解:有关left<right和left<right的区别 class Solution {public int[] searchRange(int[] nums, int target) {int nnums.length;int l0,hn-1;if(numsnull){return null; }if(n0){return new int[]{-1,-1}; }if(target&l…...

ddrnet 分割学习笔记

目录 修改后可以加载预训练: 训练自己的数据代码: 默认分割后特征下采样8倍,最后用上采样恢复到原图; 修改后可以加载预训练: import math import torch import numpy as np import torch.nn as nn import torch.nn.functional as F from torch.nn import init from …...

Outlook关闭过去事件的提醒

Outlook关闭过去事件的提醒 故障现象 最近Outlook中推出的新功能让我们可以选择自动关闭过去事件的提醒。 目前这个功能暂时只向当月通道的Office 365 订阅者发布。 这些用户升级到1810版本后&#xff0c;可以在不想收到已发生事件提醒的时候通过下面的步骤自动忽略过去事件…...

git 简单入门

git init touch test.txt git add test.txt git commit -m 初始化 仓库 git log //查找日志 git checkout -b dev //创建并切换dev分支 git branch // 查找分支 此时有master 和 dev分支&#xff0c; 此时在dev分支 dev分支也有test.txt文件 vim test.txt //写入dev …...

只有开源才能拯救AI

导语 | 随着 AI 技术的蓬勃发展&#xff0c;大模型的开源化正成为人工智能领域的新潮流&#xff0c;但同时引发的伦理和安全风险也饱受大家关注&#xff0c;如何把握平衡其中的尺度成为开源的一大难题。我们又应该如何有效进行开源治理&#xff1f;未来将走向何方&#xff1f;今…...

在Spring Boot中使用进程内缓存和Cache注解

在Spring Boot中使用内缓存的时候需要预先知道什么是内缓存&#xff0c;使用内缓存的好处。 什么是内缓存 内缓存&#xff08;也称为进程内缓存或本地缓存&#xff09;是指将数据存储在应用程序的内存中&#xff0c;以便在需要时快速访问和检索数据&#xff0c;而无需每次都从…...

YOLOv5项目实战(3)— 如何批量命名数据集中的图片

前言:Hello大家好,我是小哥谈。本节课就教大家如何去批量命名数据集中的图片,希望大家学习之后可以有所收获!~🌈 前期回顾: YOLOv5项目实战(1)— 如何去训练模型 YOLOv5项目实战(2࿰...

React + hooks + Ts 实现将后端响应的文件流(如Pdf)输出到浏览器下载

React 篇 一些关于react 学习与总结 这篇是记录开发中关于实现将后端响应的文件流&#xff08;如Pdf&#xff09;输出到浏览器下载&#xff0c;基于React Hooks Ts。 开发场景&#xff1a; 实现将后端响应的文件流&#xff08;如Pdf&#xff09;输出到浏览器下载&#xff0c;…...

大数据基础设施搭建 - JDK

一、创建目录 需要在root账号下操作&#xff0c;因为/目录下只能用root账号创建目录 1.1 创建目录 [roothadoop102 ~]# mkdir /opt/software/ [roothadoop102 ~]# mkdir /opt/module/1.2 修改权限 修改module、software文件夹的所有者和所属组均为hadoop用户&#xff0c;远程使…...

从0到0.01入门React | 010.精选 React 面试题

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…...

Docker启动SRS流媒体服务器

一、安装Docker 1.1、下载windows桌面版Windows 1.2、配置镜像 镜像加速器镜像加速器地址Docker 中国官方镜像https://registry.docker-cn.comDaoCloud 镜像站http://f1361db2.m.daocloud.ioAzure 中国镜像https://dockerhub.azk8s.cn科大镜像站https://docker.mirrors.ustc…...

php+MySQL防止sql注入

1、使用预处理语句&#xff08;Prepared Statements&#xff09;&#xff1a;预处理语句能够防止攻击者利用用户输入来篡改SQL语句&#xff0c;同时也能提高执行效率。通过将用户的输入参数与SQL语句分离&#xff0c;确保参数以安全的方式传递给数据库引擎&#xff0c;避免拼接…...

Vivado项目文件太多分不清?这份FPGA开发必备的‘文件后缀速查手册’请收好

Vivado项目文件管理终极指南&#xff1a;从后缀识别到高效工作流 当你第一次打开一个成熟的Vivado项目文件夹时&#xff0c;那种面对几十种陌生文件后缀的茫然感&#xff0c;相信每个FPGA开发者都记忆犹新。就像走进了一个满是神秘符号的仓库&#xff0c;每个文件似乎都在向你发…...

UEFI SCT编译调试踩坑记:我的AARCH64环境搭建与问题解决实录

UEFI SCT编译调试实战&#xff1a;AARCH64环境搭建与疑难问题全解析 当你在深夜的办公室里盯着屏幕上闪烁的光标&#xff0c;第N次尝试编译UEFI SCT测试套件时&#xff0c;那种既熟悉又陌生的挫败感再次袭来。作为UEFI开发者&#xff0c;我们都经历过这样的时刻——官方文档看似…...

抖音下载器:从零开始,轻松获取无水印视频的完整指南

抖音下载器&#xff1a;从零开始&#xff0c;轻松获取无水印视频的完整指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallb…...

如何在旧款Mac上安装最新macOS:OpenCore Legacy Patcher完整指南

如何在旧款Mac上安装最新macOS&#xff1a;OpenCore Legacy Patcher完整指南 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 还在为苹果官方停止支持的老旧Ma…...

AI辅助架构设计:让快马智能生成符合最佳实践的SpringBoot项目骨架

今天想和大家聊聊如何用AI工具快速搭建一个符合现代最佳实践的SpringBoot项目骨架。作为一个经常需要从零开始搭建项目的开发者&#xff0c;我发现传统的手动创建项目方式效率太低&#xff0c;而且容易遗漏一些关键配置。最近尝试了InsCode(快马)平台的AI辅助功能&#xff0c;发…...

手把手教你搭建RAG知识库:从零到一,让你的知识库从“仓库”变“助手”!

本文详细介绍了如何搭建RAG知识库&#xff0c;通过四个核心组件——文档处理器、嵌入模型、向量数据库和大语言模型&#xff0c;实现知识的有效管理和利用。文章以作者自制的知识工场为例&#xff0c;阐述了从文档处理、知识拆解、向量化到存储、检索和回答的完整流程&#xff…...

太阳能家用电池电源市场:预计到2032年将达到98.8亿美元

在全球能源转型与地缘政治风险交织的背景下&#xff0c;家庭能源自主性需求正催生一个高速增长的细分市场。据 恒州诚思&#xff08;YH Research&#xff09; 《全球太阳能家用电池电源市场报告2026-2032》预测&#xff0c;2032年该市场规模将达98.8亿美元&#xff0c;2026-203…...

Java基础实战:用快马平台快速构建学生成绩管理系统巩固核心知识

最近在复习Java基础知识&#xff0c;发现光看理论很容易遗忘&#xff0c;于是决定通过一个小项目来巩固核心概念。这个简易学生成绩管理系统虽然功能简单&#xff0c;但涵盖了Java基础的多个重要知识点&#xff0c;特别适合像我这样的初学者练手。 项目整体设计思路 首先考虑…...

从数学直觉到代码实践:Harris角点检测的算法拆解与性能调优

1. 角点检测&#xff1a;计算机视觉的基石 想象一下你正在玩一个拼图游戏。当两块拼图能够严丝合缝地拼接在一起时&#xff0c;往往是因为它们在某些关键位置完美匹配——这些位置通常是拼图块的拐角处。计算机视觉中的角点检测&#xff0c;本质上就是在做类似的事情&#xff1…...

CodeMaker:重新定义开发者效率的智能编码助手

CodeMaker&#xff1a;重新定义开发者效率的智能编码助手 【免费下载链接】CodeMaker A idea-plugin for Java/Scala, support custom code template. 项目地址: https://gitcode.com/gh_mirrors/co/CodeMaker 核心价值&#xff1a;告别重复编码&#xff0c;拥抱智能开发…...