【C#】泛型

【C#】泛型

泛型是什么

泛型是将类型作为参数传递给类、结构、接口和方法,这些参数相当于类型占位符。当我们定义类或方法时使用占位符代替变量类型,真正使用时再具体指定数据类型,以此来达到代码重用目的。

泛型特点

  1. 提高代码重用性
  2. 一定程度避免装箱拆箱

泛型分类

声明 泛型类 基本语法:

csharp 复制代码
class 类名<泛型占位字母>

声明 泛型结构 基本语法:

csharp 复制代码
struct 结构名<泛型占位字母>

声明 泛型接口 基本语法:

csharp 复制代码
interface 接口名<泛型占位字母>

声明 泛型函数 基本语法:

csharp 复制代码
函数名<泛型占位字母>(参数列表)
复制代码
注意:泛型占位字母可以有多个,用逗号分开

代码展示

1. 泛型类

csharp 复制代码
class TestClass<T>
{
    public T value;
}
class TestClass2<T1, T2, K, J>
{
    public T1 value1;
    public T2 value2;
    public K value3;
    public J value4;
}
class Program
{
    static void Main(string[] args)
    {
        //使用时必须指定具体数据类型,如:int类型
        TestClass<int> t = new TestClass<int>();
        t.value = 5;
        Console.WriteLine(t.value);//输出:5
    
        //再创建一个对象,将泛型指定为string类型,这里说明泛型可以提高代码重用性
        TestClass<string> t2 = new TestClass<string>();
        t2.value = "123456";
        Console.WriteLine(t2.value);//输出:123456
    
        //创建一个有多个泛型类的对象
        TestClass2<int, string, bool, TestClass<float>> t3 = new TestClass2<int, string, bool, TestClass<float>>();
        
        Console.ReadLine();
    }
}

2. 泛型结构体

csharp 复制代码
struct TestStruct<T>
{
    public T value;
}
class Program
{
    static void Main(string[] args)
    {
        //创建结构体对象
        TestStruct<bool> ts = new TestStruct<bool>();
        Console.WriteLine(ts.value);//输出:False
        
        Console.ReadLine();
    }
}

3. 泛型接口及类继承

csharp 复制代码
interface TestInterface<T>
{
    T value
    {
        get;
        set;
    }
}

class Test : TestInterface<int>
{
    private int myValue;
    public int value 
    {
        get
        {
            return myValue;
        }
        set
        {
            myValue = value;
        }
    }
}
class Program
{
    static void Main(string[] args)
    {
        //创建接口实例,Test类是实现 指定泛型为int类型的接口 的类,所以创建接口实例时,泛型指定类型必须与Test类指定的泛型类型一致 即int类型
        TestInterface<int> it = new Test();
        it.value = 100;
        Console.WriteLine(it.value);//输出:100
        
        Console.ReadLine();
    }
}

创建接口实例时,泛型指定类型必须与Test类指定的泛型类型不一致 时,会报错。

4. 泛型方法

  1. 普通类中的泛型方法
csharp 复制代码
class Test2
{
    //泛型作为参数传递
    public void TestFun<T>(T value)
    {
        Console.WriteLine(value);
    }

    //泛型作为返回值
    public T TestFun<T>(bool v)
    {
        return default(T);
    }

    //泛型既不作为参数传递 也不作为返回值
    public void TestFun<T>()
    {
        //用参数类型在里面进行逻辑处理,例如:
        T t = default(T);//获得类型的默认值方法:default()
        Console.WriteLine(t);
    }

    //多个泛型作为参数传递
    public void TestFun<T, K, M>(T t, K k, M m)
    {

    }
}
class Program
{
    static void Main(string[] args)
    {
        //创建Test2对象
        Test2 tt = new Test2();
        tt.TestFun<float>(12.5f);//作为参数传递时 输出:12.5
        tt.TestFun<string>(true);//作为返回值
        tt.TestFun<int>();//既不作为参数传递 也不作为返回值  输出:0
        tt.TestFun<int, double, bool>(1, 8.888888, false);//多个作为参数传递
        
        Console.ReadLine();
    }
}
  1. 泛型类中的泛型方法
csharp 复制代码
//Test2 与 Test2<T> 名字一样但是后者有泛型,就相当于新的类,两个类是不一样的
class Test2<T>
{
    public T value;

    //这个不叫泛型方法 因为 T是泛型类声明的时候 就指定的 在使用这个函数的时候 不能进行动态变化
    public void TestFun(T t)
    {
        Console.WriteLine("No :" + t);
    }

    //这个才是泛型方法 一直是方法名后面加了尖括号并且有占位符
    public void TestFun<K>(K k)
    {
        Console.WriteLine("YES :" + k);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Test2<int> tt2 = new Test2<int>();
        //这两个不是同一个方法
        tt2.TestFun(156);//输出:No :156
        tt2.TestFun<int>(156);//输出:YES :156
        //这两个同一个方法
        tt2.TestFun<string>("123");//输出:YES :123
        tt2.TestFun("789");//输出:YES :789
    }
}

tt2.TestFun(156); 与 tt2.TestFun(156); 调用的方法如下:

tt2.TestFun("123"); 与 tt2.TestFun("789"); 调用的方法如下:

复制代码
【tt2】是一个泛型为【int类型】的【Test2】对象,使用tt2.TestFun()方法时,传入的参数与对象的泛型一致时,则会调用【public void TestFun(T t)】。传入的参数与对象的泛型不一致时,则会调用同名的泛型方法【public void TestFun<K>(K k)】,且调用时可以省略尖括号【<>】,通过参数直接判断该方法的泛型数据类型。

小结

  1. 声明泛型时,就是一个任意类型的占位符,真正起作用是在使用它时。
  2. 泛型占位符至少有一个,可以有无数个,多个时用逗号分隔开。
  3. 文章提到的default目的是用来获取任意类型的默认值的。

因为作者精力有限,文章中难免出现一些错漏,敬请广大专家和网友批评、指正。

相关推荐
忆源7 分钟前
【Qt】之音视频编程1:QtAV的背景和安装篇
开发语言·qt·音视频
敲键盘的小夜猫10 分钟前
Python核心数据类型全解析:字符串、列表、元组、字典与集合
开发语言·python
李匠202413 分钟前
C++GO语言微服务之图片、短信验证码生成及存储
开发语言·c++·微服务·golang
巨龙之路3 小时前
C语言中的assert
c语言·开发语言
2301_776681654 小时前
【用「概率思维」重新理解生活】
开发语言·人工智能·自然语言处理
码小跳4 小时前
Halcon案例(一):C#联合Halcon识别路由器上的散热孔
图像处理·c#
熊大如如5 小时前
Java 反射
java·开发语言
ll7788115 小时前
C++学习之路,从0到精通的征途:继承
开发语言·数据结构·c++·学习·算法
我不想当小卡拉米5 小时前
【Linux】操作系统入门:冯诺依曼体系结构
linux·开发语言·网络·c++
teacher伟大光荣且正确5 小时前
Qt Creator 配置 Android 编译环境
android·开发语言·qt