C#之泛型

泛型的用处非常大,我们编程的时候,有时候感觉不到它的存在,原因就是我们的代码过于简单,或者架构比较陈旧,所以用不用感觉不出来,一般高级框架里面就有大量的泛型。

泛型的优点有:代码重用、类型安全、高效率,凡是带有<>的尖括号,都是泛型的表示。

以下案例来自.net6环境

1.泛型由来,为什么要用泛型

以下3组不同类型的数据,定义的时候,我们必须知道类型,否则无法定义,而且后期不能再次增加或者减少数据

int[] a = new int[2] { 1, 2 };  //定义一个int类型的数组
double[] b = new double[2] { 1.0, 2.0 };  //定义一个double类型的数组
string[] c = new string[2] { "张三", "李四" }; //定义一个string类型的数组

于是,后来有了ArrayList,不需要知道类型,ArrayList中的Add方法可以增加任何类型的数据,但是有装箱拆箱的性能损失。

ArrayList list1 = new ArrayList();   //定义一个ArrayList
list1.Add(1);       //   int类型
list1.Add(1.0);       //  double类型
list1.Add("张三");     //      string类型

再后来,我们使用泛型List<T>,其中T,可以是任何类型,不仅解决数组不能自由改变的问题,还不会有性能的问题。

List<int> list2 = new List<int>();
list2.Add(1);
list2.Add(5);

List<string> list3 = new List<string>();
list3.Add("张三");
list3.Add("李四");

2.泛型方法

如果不用泛型方法,那么Show需要定义3个类型的方法,分别是int double string。这里使用泛型方法后,只需要一个方法即可,并且在调用的时候,指定类型,然后传递参数,代码重用,效率高等等有点。

当参数使用,无返回值

Show<int>(3);   //调用的时候指定int类型
Show<double>(3.0);   //调用的时候指定int类型
Show<string>("张三");   //调用的时候指定int类型

static void Show<T>(T param)
{
    Console.WriteLine($"类型:{param?.GetType().Name + param}");     //?表示可空
}

当返回值使用,

Show1<int>();   //调用的时候指定int类型
static T? Show1<T>()         //?表示可空
{
    return default(T);   //值类型不能为null,引用类型可以为null
}

 当局部使用

Show2<double>(2,3);   //调用的时候指定int类型
static void Show2<T>(int a,int b)        
{
    T t;//j局部变量  string的时候t是null   int的时候t是0  double也是0   
}

3.泛型类

定义一个泛型类

public class Alist<T>
{
    private Alist<T>? alist;     //?表示可空
    public void Add(T param)
    {
        alist?.Add(param);         //?表示可空
    }
}

使用泛型类

Alist<int> list = new Alist<int>();       //实例化调用,调用的时候指定类型,int
list.Add(123);

4.泛型的约束

 where T:class,需要传递引用类型,只要是引用类型都行,比如传递string,或者Alist<T>。

A<string>();   //调用,并且指定string

A<Alist<int>>();   //调用,并且指定为引用类型的Alist<T> 

static void A<T>() where T:class      //class是引用类型
{

}
public class Alist<T> 
{
    private Alist<T>? alist;     //?表示可空
    public void Add(T param)
    {
        alist?.Add(param);         //?表示可空
    }
}

where T:struct, 需要传递值类型,只要是值类型都行,比如传递int,double。

值类型都有一个隐式的公共构造方法

A1<int>();    //调用,并且指定int
A1<double>();       //调用,并且指定double

static T A1<T>() where T : struct      //struct是值类型
{
    return new T();//值类型都有一个隐式的公共构造方法
}

where T : new() ,要放在最后。包含(值类型,值类型就有构造参数)和(引用类型带构造参数的)

A2<int>();        //调用,并且指定int  int是值类型,有构造方法
A2<Alist<string>>();      //调用,并且指定Alist<string>  Alist<string>是引用类型,也有构造方法
static void A2<T>() where T : new()      //new,包含(值类型)和(引用类型带构造参数的)
{

}


public class Alist<T>
{
    public Alist()     //构造方法      不写构造方法就不行了
    {

    }
    private Alist<T>? alist;     //?表示可空
    public void Add(T param)
    {
        alist?.Add(param);         //?表示可空
    }
}

 where T : B ,自定义约束,B是一个类,只能是B或者继承B类的(C也行)

A3<B>();   //调用,并且指定B  
A3<C>();     //调用,并且指定C  
static void A3<T>() where T : B      //B,自定义约束,只能是B或者继承B类的(C也行)
{

}


public class B
{

}

public class C : B
{

}

可以约束多个接口,一个参数有多个约束

static void A4<T>() where T : B,AA,AA1     //可以约束多个接口
{

}

interface AA
{

}
interface AA1
{

}

也可以 多个参数中每个参数都有一个或者多个约束

A5<B, AA, C>();   //D调用
static void A5<T, T1, T2>()
    where T : B
    where T1 : AA
    where T2 : C     
{

}

 所有代码

using System.Collections;

int[] a = new int[2] { 1, 2 };  //定义一个int类型的数组
double[] b = new double[2] { 1.0, 2.0 };  //定义一个double类型的数组
string[] c = new string[2] { "张三", "李四" }; //定义一个string类型的数组


ArrayList list1 = new ArrayList();   //定义一个ArrayList
list1.Add(1);       //   int类型
list1.Add(1.0);       //  double类型
list1.Add("张三");     //      string类型

List<int> list2 = new List<int>();
list2.Add(1);
list2.Add(5);

List<string> list3 = new List<string>();
list3.Add("张三");
list3.Add("李四");

//Show<int>(3);   //调用的时候指定int类型
//Show<double>(3.0);   //调用的时候指定int类型
//Show<string>("张三");   //调用的时候指定int类型

//static void Show<T>(T param)
//{
//    Console.WriteLine($"类型:{param?.GetType().Name + param}");     //?表示可空
//}

//Show1<int>();   //调用的时候指定int类型
//static T? Show1<T>()         //?表示可空
//{
//    return default(T);   //值类型不能为null,引用类型可以为null
//}


//Show2<double>(2,3);   //调用的时候指定int类型
//static void Show2<T>(int a,int b)        
//{
//    T t;//j局部变量  string的时候t是null   int的时候t是0  double也是0   
//}

//Alist<int> list = new Alist<int>();       //实例化调用,调用的时候指定类型,int
//list.Add(123);
//Console.WriteLine(list);

//A<string>();   //调用,并且指定string

//A<Alist<int>>();   //调用,并且指定为引用类型的Alist<T> 


//A1<int>();    //调用,并且指定int
//A1<double>();       //调用,并且指定double
//static void A<T>() where T : class      //class是引用类型
//{

//}


//static T A1<T>() where T : struct      //struct是值类型
//{
//    return new T();    //值类型都有一个隐式的公共构造方法
//}
//A2<int>();        //调用,并且指定int  int是值类型,有构造方法
//A2<Alist<string>>();      //调用,并且指定Alist<string>  Alist<string>是引用类型,也有构造方法
//static void A2<T>() where T : new()      //new,包含(值类型)和(引用类型带构造参数的)
//{

//}
//A3<B>();   //调用,并且指定B  
//A3<C>();     //调用,并且指定C  
//static void A3<T>() where T : B      //B,自定义约束,只能是B或者继承B类的(C也行)
//{

//}


static void A4<T>() where T : AA, AA1    //可以约束多个接口
{

}
A5<B, AA, C>();   //D调用
static void A5<T, T1, T2>()
    where T : B
    where T1 : AA
    where T2 : C
{

}

interface AA
{

}
interface AA1
{

}

public class A
{

}
public class B
{

}

public class C : B
{

}


public class Alist<T>
{
    public Alist()     //构造方法      不写构造方法就不行了
    {

    }
    private Alist<T>? alist;     //?表示可空
    public void Add(T param)
    {
        alist?.Add(param);         //?表示可空
    }
}


来源:C#之泛型_c#泛型数组获取长度_故里2130的博客-CSDN博客

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

故里2130-西安找工作

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值