首页 > 编程语言 >C#泛型

C#泛型

时间:2024-08-19 11:42:02浏览次数:5  
标签:C# 接口 public 类型 参数 泛型 class

image

泛型(Generics)是C#中的一个重要特性,它允许您编写灵活、类型安全且可重用的代码。下面我将详细介绍泛型的概念、使用方法及其在C#中的实现细节。

泛型的基本概念

1. 什么是泛型?

泛型是一种允许您定义类型参数的机制,这些类型参数可以在编译时由具体的类型替换。这样,您可以编写一个通用的类或方法,然后在使用时指定具体的类型,从而获得类型安全和性能优势。

2. 为什么使用泛型?

  • 类型安全:编译器会在编译阶段检查类型一致性,避免运行时错误。
  • 代码重用:通过定义泛型类型或方法,可以编写一次代码并应用于多种数据类型。
  • 性能提升:避免了装箱和拆箱操作,减少了运行时的类型转换开销。

泛型的使用

1. 定义泛型类型

定义一个泛型类、接口或结构体时,需要在类型声明后面加上类型参数列表,使用尖括号 <T> 来指定类型参数。

public class Stack<T>
{
    private T[] elements;
    private int top;

    public void Push(T item)
    {
        // 添加元素到堆栈
    }

    public T Pop()
    {
        // 移除并返回顶部元素
        return default(T);
    }
}

2. 定义泛型方法

在方法声明后面加上类型参数列表,可以创建泛型方法。

public static T Max<T>(T x, T y)
{
    return x.CompareTo(y) > 0 ? x : y;
}

3. 使用泛型

要使用泛型类型或方法,您需要在实例化或调用时提供具体的类型。

Stack<int> intStack = new Stack<int>();
int maxInt = Max(3, 5);

Stack<string> stringStack = new Stack<string>();
string maxString = Max("hello", "world");

泛型约束

为了确保泛型类型或方法能够正确工作,您可以对类型参数添加约束。这可以限制泛型类型参数的有效范围。

  • where 关键字:用于指定类型约束。
  • classstruct:限制类型参数只能是引用类型或值类型。
  • new():要求类型参数必须有一个公共的无参数构造函数。
public class Example<T> where T : new()
{
    public T CreateInstance()
    {
        return new T();
    }
}
  • 接口或基类:要求类型参数必须实现某个接口或继承自某个基类。
public class Example<T> where T : IComparable<T>
{
    public void Sort(List<T> list)
    {
        // 可以安全地使用 IComparable 接口
    }
}

泛型和接口

您可以定义泛型接口,也可以在接口中使用泛型。

public interface IComparer<T>
{
    int Compare(T x, T y);
}

public class StringComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        return x.CompareTo(y);
    }
}

泛型和继承

泛型类型可以继承自非泛型类型,也可以作为泛型类型的一部分。

public class BaseClass { }
public class GenericClass<T> : BaseClass { }

public class DerivedGenericClass<T> : GenericClass<T> { }

标签:C#,接口,public,类型,参数,泛型,class
From: https://www.cnblogs.com/ayic/p/18366990

相关文章

  • ceph-messenger模块代码走读(1)
    messenger代码走读messenger的使用以mgr代码为例,看看messengrr的初始化和启动。//构造函数,初始化一个client_messenger对象。MgrStandby::MgrStandby(intargc,constchar**argv):Dispatcher(g_ceph_context),monc{g_ceph_context,poolctx},client_messenger(M......
  • 达梦数据库部署案例之---DMDSC共享存储集群部署
    案例说明:在Linux环境下部署DMDSC共享存储集群。适用版本:DM8操作系统版本:[root@node201KingbaseHA]#cat/etc/centos-releaseCentOSLinuxrelease7.9.2009(Core)集群架构:如下所示,node1和node2为集群节点:节点信息:[root@node201KingbaseHA]#vi/etc/hosts192.......
  • 【团队建设】如何做好团队开发中的 CodeReview(代码评审)?
    合集-团队建设(1) 1.【团队建设】如何做好团队开发中的CodeReview(代码评审)?08-19收起  目录前言一、为什么要做二、有哪些好处三、具体怎么做3.1评审条件3.2评审重点3.3评审形式四、还可以怎么做4.1提出亮点4.2轮流评审4.2文档沉淀五、文......
  • 【JavaSec】类的动态加载初探
    0x02类的动态加载文章目录0x02类的动态加载什么是类加载?动态类加载方法:类加载:继承关系:调用关系:下面尝试使用URLClassLoader进行尝试http协议:jar协议:http读取方法:file读取方法:使用defineClass类加载方法Unsafe类加载什么是类加载?即虚拟机加载.class文件在......
  • docker 容器迁移
    第一步:使用dockercommit命令将运行中的容器保存为新的镜像。这里需要容器的ID或名称,以及你想要命名的目标镜像名dockercommit[容器ID或名称][目标镜像名]:[标签]#例如:dockercommitmy_containermy_new_image:latest第二步:使用dockersave命令将刚才创建的镜像保存为tar......
  • CANoe_UDS-boorloader 自动化测试系列(二)基本功能:CAPL实现UDS协议下的CAN报文接收#解析
    目录一、前言二、CAPL实现1、报文接收接收报文函数:2、报文发送发送报文函数:三、总结展望一、前言halle,大家好,我是小鸟鹏。上篇文章《CANoe_UDS-boorloader自动测试系列(二)基本刷写流程》简单介绍了整Bootloader的基本刷写流程,包括具体使用哪些服务实现哪些功能,对......
  • P5221 Product
    P5221Product求\(\prod_{i=1}^N\prod_{j=1}^N\frac{lcm(i,j)}{gcd(i,j)}\(\bmod\104857601)\)如果是上下同时除gcd的话会发现有点困难,但是如果上下同时乘一个gcd,会发现上面变得非常简单。我们要求的就是分母\(\prod_{i=1}^N\prod_{j=1}^N{(i,j)^2}(\bmod\104857601)\)直......
  • 嵌入式初学-C语言-二五
    构造类型   数据类型分类:基本类型:整数型短整型:short(2字节)整型:int(4个字节)长整型:long(8个字节)长长整型:longlong浮点型单精度:float(4个字节)双精度:double(8个字节)字符型:char(1个字节)指针类型数据类型*:int*,char*,float*等void*:任意数据类型指针空类型void......
  • 小龙dev cpp6.0版本 文件名读取bug
     问题阐述:见如下代码:输出0-60的正整数文件名为“ceshi.c”//测试#include<stdio.h>intmain(void){ intn=0; for(inti=0;i<=60;i++){ printf("%d\t",i); n++; if(n%5==0){ printf("\n"); } }}运行结果如下另一个文件代码如下,......
  • c语言 小熊猫Dev cpp6.7.5版本bug
    问题描述:请看下面代码#include<stdio.h>#include<math.h>intmain(void){ intres=0; inti=2; res=pow(10,i); printf("%d",res); return0;}期望输出100,但是在pandaDevcpp6.7.5版本中会输出99在看下面的代码正确输出100#include<stdio.h>#include<ma......