【从零开始入门unity游戏开发之——C#篇29】C#泛型(T)和 泛型约束

server/2024/12/28 5:45:24/

文章目录

  • 一、泛型
    • 1、泛型是什么
    • 2、泛型分类
      • 2.1. **泛型类和泛型接口**
      • 2.2. **泛型方法**
    • 3、泛型类和接口
      • 3.1 泛型类示例:
      • 3.2 泛型接口示例:
      • 3.3 泛型类接受多个类型参数:
    • 4、泛型方法
      • 4.1. **普通类中的泛型方法**
      • 4.2. **泛型类中的泛型方法**
    • 5、泛型的作用
    • 6、总结
  • 二、泛型约束
    • 1、**基本的泛型约束**
    • 2、各泛型约束详细讲解
      • 2.1. **值类型约束(`struct`)**
      • 2.2. **引用类型约束(`class`)**
      • 2.3. **公共无参构造函数约束(`new()`)**
      • 2.4. **类约束(`BaseClass`)**
      • 2.5. **接口约束(`IInterface`)**
      • 2.6. **另一个泛型约束(`T : U`)**
    • 3、泛型约束的组合使用
    • 4、总结
  • 专栏推荐
  • 完结

一、泛型

1、泛型是什么

泛型是通过类型参数化来实现代码重用的机制。它允许你在编写类或方法时,使用类型占位符(通常是一个字母),并在实际使用时指定具体的类型。泛型使得同一份代码能够处理多种类型,提高了代码的灵活性和可维护性。

2、泛型分类

2.1. 泛型类和泛型接口

// 泛型类的基本语法:
class ClassName<T> { }// 泛型接口的基本语法:
interface InterfaceName<T> { }

2.2. 泛型方法

// 泛型方法的基本语法:
ReturnType MethodName<T>(Parameters) { }
// 可以有多个泛型参数
ReturnType MethodName<T1, T2>(Parameters) { }

3、泛型类和接口

3.1 泛型类示例:

class TestClass<T>
{public T value;
}// 使用泛型类时指定类型
TestClass<int> t1 = new TestClass<int>();
t1.value = 10;
Console.WriteLine(t1.value); // 输出: 10TestClass<string> t2 = new TestClass<string>();
t2.value = "Hello";
Console.WriteLine(t2.value); // 输出: Hello

3.2 泛型接口示例:

interface ITestInterface<T>
{T Value { get; set; }
}class Test : ITestInterface<int>
{public int Value { get; set; }
}

3.3 泛型类接受多个类型参数:

class TestClass2<T1, T2, T3>
{public T1 Value1;public T2 Value2;public T3 Value3;
}TestClass2<int, string, float> test = new TestClass2<int, string, float>();
test.Value1 = 10;
test.Value2 = "Test";
test.Value3 = 3.14f;

4、泛型方法

4.1. 普通类中的泛型方法

class Test
{public void TestMethod<T>(T value){Console.WriteLine(value);}
}Test test = new Test();
test.TestMethod<int>(10); // 输出: 10
test.TestMethod<string>("Hello"); // 输出: Hello

4.2. 泛型类中的泛型方法

class TestClass<T>
{public void TestMethod<K>(K value){Console.WriteLine(value);}
}TestClass<int> test = new TestClass<int>();
test.TestMethod<string>("Test Method");

5、泛型的作用

  • 相同逻辑处理不同类型的对象:泛型可以用来编写处理不同类型对象的相同逻辑的代码,避免重复编写相似的代码。

  • 避免装箱拆箱:泛型可以避免值类型(如 int)在集合类(如 ArrayList)中进行装箱拆箱操作,减少性能开销。

6、总结

  • 泛型是一个类型占位符,在编写代码时并不指定具体类型,直到使用时再指定。
  • 泛型的类型占位字母可以有多个,并用逗号分开。
  • 泛型占位字母通常是大写字母(如 TKV 等)。
  • 不确定泛型类型时,获取默认值,可以使用 default(T) 获取类型的默认值。
  • 看到<>包括的字母,那肯定是泛型。

二、泛型约束

在 C# 中,泛型约束用于限制泛型类型参数必须满足的条件。这使得泛型代码更加灵活和类型安全,同时避免了某些运行时错误。通过泛型约束,可以确保泛型类型参数遵循特定的行为或者接口,增强代码的可预测性和可靠性。

1、基本的泛型约束

泛型约束是在泛型声明中通过 where 关键字定义的,基本的语法如下:

class ClassName<T> where T : Constraint
{// T 是满足 Constraint 的类型
}

2、各泛型约束详细讲解

2.1. 值类型约束(struct

  • 该约束要求泛型类型参数是值类型,不能是引用类型。
  • 常见的值类型有:int, float, double, struct 自定义值类型。
class Test1<T> where T : struct
{public T value;public void TestFun<K>(K y) where K : struct{// 只能传入值类型}
}// 使用示例
Test1<int> t1 = new Test1<int>();
t1.TestFun<float>(1.3f);  // 可以传递float,因为float是值类型

2.2. 引用类型约束(class

  • 该约束要求泛型类型参数是引用类型,可以是任何类、接口或委托类型。
class Test2<T> where T : class
{public T value;public void TestFun<K>(K y) where K : class{// 只能传入引用类型}
}// 使用示例
Test2<Random> t2 = new Test2<Random>();
t2.value = new Random();
t2.TestFun<object>(new object());  // 可以传递object,因为它是引用类型

2.3. 公共无参构造函数约束(new()

  • 该约束要求泛型类型参数必须具有公共无参构造函数,可以在代码中使用 new() 创建实例。
class Test3<T> where T : new()
{public T value;public Test3(){value = new T();  // 创建T类型的实例}
}class Test1 { }Test3<Test1> t3 = new Test3<Test1>();  // Test1必须有公共无参构造函数

补充知识
类的无参构造函数知识点你可能已经忘记了,这里补充一下。

在 C# 中,默认情况下每个类都会有一个 隐式无参构造函数,如果你没有显式地定义构造函数。也就是说,在你声明一个空的类 Test1 时,它会自动获得一个无参构造函数,虽然你没有写出这个构造函数。

class Test1
{// 这里没有显式写构造函数
}

上面的代码实际上等价于:

class Test1
{// 默认无参构造函数public Test1() { }
}

如果你在类中显式定义了其他构造函数(例如带参数的构造函数),那么编译器 不会 自动生成无参构造函数。此时,如果你需要无参构造函数,必须显式地提供。

例如,以下代码就不会自动提供无参构造函数:

class Test1
{public Test1(int x) { }  // 显式定义了带参数的构造函数
}

如果你希望仍然能够使用无参构造函数,你需要显式定义它:

class Test1
{public Test1() { }  // 显式定义无参构造函数public Test1(int x) { }  // 仍然可以有带参数的构造函数
}

2.4. 类约束(BaseClass

  • 该约束要求泛型类型参数必须是某个类及其派生类。
class Test4<T> where T : Test1
{public T value;
}class Test3 : Test1 { }Test4<Test3> t4 = new Test4<Test3>();  // Test3是Test1的派生类

2.5. 接口约束(IInterface

  • 该约束要求泛型类型参数实现某个接口。
interface IFly { }class Test4 : IFly { }class Test5<T> where T : IFly
{public T value;
}Test5<Test4> t5 = new Test5<Test4>();  // Test4实现了IFly接口

2.6. 另一个泛型约束(T : U

  • 该约束要求泛型类型 T 必须是另一个泛型类型 U 或其派生类。
class Test6<T, U> where T : U
{public T value;
}class Test4 { }Test6<Test4, object> t6 = new Test6<Test4, object>();  // Test4是object的派生类

3、泛型约束的组合使用

泛型约束可以组合使用,这样可以同时限制多个条件。多个约束用 where 关键字连接。

class Test7<T> where T : class, new()  // T必须是引用类型并且有公共无参构造函数
{public T value;
}class Test8<T, K> where T : class, new() where K : struct  // T需要满足引用类型并有构造函数,K是值类型
{public T value;public K key;
}

4、总结

  • 泛型约束使得我们可以对泛型类型参数进行类型限制,从而避免运行时错误,增强类型安全。
  • 常见的泛型约束包括:class, struct, new(), 类名、接口名以及其他泛型类型。
  • 这些约束可以组合使用,确保泛型类型参数在特定的约束范围内。

通过合理使用泛型约束,开发者可以确保程序在不同类型数据处理时的一致性和安全性。


专栏推荐

地址
【从零开始入门unity游戏开发之——C#篇】
【从零开始入门unity游戏开发之——unity篇】
【制作100个Unity游戏】
【推荐100个unity插件】
【实现100个unity特效】
unity框架开发】

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇,https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!如果你遇到任何问题,也欢迎你评论私信或者加群找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~
在这里插入图片描述


http://www.ppmy.cn/server/153826.html

相关文章

List详解

List详解 在Java中&#xff0c;List是一个接口&#xff0c;它继承自Collection接口。List接口为数据的有序集合提供了操作接口&#xff0c;其中可以包含重复的元素。这个接口的实现类以特定的方式存储元素&#xff0c;允许元素根据索引进行访问&#xff0c;同时还支持通过迭代…

【分布式文件存储系统Minio】2024.12保姆级教程

文章目录 1.介绍1.分布式文件系统2.基本概念 2.环境搭建1.访问网址2.账号密码都是minioadmin3.创建一个桶4.**Docker安装miniomc突破7天限制**1.拉取镜像2.运行容器3.进行配置1.格式2.具体配置 4.查看桶5.给桶开放权限 3.搭建minio模块1.创建一个oss模块1.在sun-common下创建2.…

网络安全的学习方向和路线是怎么样的?

最近有同学问我&#xff0c;网络安全的学习路线是怎么样的&#xff1f; 废话不多说&#xff0c;先上一张图镇楼&#xff0c;看看网络安全有哪些方向&#xff0c;它们之间有什么关系和区别&#xff0c;各自需要学习哪些东西。 在这个圈子技术门类中&#xff0c;工作岗位主要有以…

Python小括号( )、中括号[ ]和大括号{}代表什么

python语言最常见的括号有三种&#xff0c;分别是&#xff1a;小括号( )、中括号[ ]和大括号也叫做花括号{ }&#xff0c;分别用来代表不同的python基本内置数据类型。 小括号&#xff08;&#xff09;&#xff1a;struct结构体&#xff0c;但不能改值 python中的小括号( )&am…

VBA技术资料MF243:利用第三方软件复制PDF数据到EXCEL

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

中间件xxl-job安装

拉取镜像 docker pull xuxueli/xxl-job-admin:2.4.2 创建xxl-job-admin容器 docker create --name xxl-job-admin -p 9099:8080 -e PARAMS"--spring.datasource.urljdbc:mysql://192.168.96.57:3306/xxl_job2Unicodetrue&characterEncodingUTF-8 --spring.dataso…

C#都可以找哪些工作?

在国内学习C#&#xff0c;可以找的工作主要是以下4个&#xff1a; 1、游戏开发 需要学习C#编程、Unity引擎操作、游戏设计和3D图形处理等。 2、PC桌面应用开发 需要学习C#编程、WinForm框架/WPF框架、MVVM设计模式和UI/UX设计等。 3、Web开发 需要学习C#编程、ASP.NET框架…

深入理解 Docker 网桥配置与网络管理

目录 引言Docker 网络概述Docker 默认网络模式 3.1 Bridge 模式3.2 Host 模式3.3 None 模式 Docker Bridge 网络原理解析 4.1 Bridge 网络的基本架构4.2 网桥的创建与配置4.3 容器与 Bridge 的连接机制 配置自定义 Docker 网桥 5.1 创建自定义网桥5.2 配置子网和网关5.3 管理容…