泛型是什么?

这是摘自百度百科中对泛型的介绍:

泛型是c#2.0的一个新增加的特性,它为使用c#语言编写面向对象程序增加了极大的效力和灵活性。不会强行对值类型进行装箱和拆箱,或对引用类型进行向下强制类型转换,所以性能得到提高。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设,所以泛型提高了程序的类型安全。它允许程序员将一个实际的数据类型的规约延迟至泛型的实例被创建时才确定。泛型为开发者提供了一种高性能的编程方式,能够提高代码的重用性,并允许开发者编写非常优雅的解决方案。

看过之后,会用的还是懂;不会用的,也还是不懂。

所以我们还是看看泛型具体在程序中的应用:

//泛型方法
//unity3D中用的最多的泛型方法应该是GetCompent<T>
//T就是占位符,当调用这个方法的你要告诉编译器,这个T的具体类型。
//另外,"T"只是一个标识,完全可以用其他代替,如"K","MyType"等,只是使用习惯。
//比如:
GameObject player;
Animator animator;
void Start()
{
//在场景中找到名为MyPlayer物体
player = GameObject.Find("MyPlayer");
//获取该物体上的Animator组件
animator = player.GetComponent<Animator>();
//对于使用AddComponent<T>()、GetCompent<T>()这两个泛型方法来说,需要了解的就是:T就是你想要的具体的组件类型。
//对于泛型方法来说,泛型的作用就是占位和约束的作用。
}
//下面来说声明泛型函数
/// <summary>
/// 比较等级;
/// </summary>
/// <returns>
/// 若t1>=t2的等级,则返回true;否则返回false
/// </returns>
/// where T : IRole where K : IRole的作用是约束传入的两个参数类型必须要实现IRole这个接口;
/// 这样就定义好了一个泛型方法
public bool CompareLevel<T,K>(T t1, K t2) where T : IRole where K : IRole
{
//因为泛型t1,t2都被约束需要实现接口,所以我们可以强制转换到IRole来获取level比较
return ((IRole)t1).level >= ((IRole)t2).level;
}
//那么怎么使用呢?
//接下来看:
public void Test()
{
//先定义三个测试用的类型
MyNPC npc =new MyNPC();
MyPlayer player =new MyPlayer();
MyMonster monster =new MyMonster();
//对各个类型的level赋值
npc.level =;
player.level =;
monster.level =;
//比较npc和player的level就很简单了,只需要这样调用即可
bool b1 = CompareLevel<MyNPC,MyPlayer>(npc,player); //npc?payer//false
bool b2 = CompareLevel<MyNPC,MyMonster>(npc,monster);//npc?monster//false
bool b3 = CompareLevel<MyPlayer,MyMonster>(player,monster);//payer?monster//false
} public interface IRole
{
int level{get;set;}
}
public class MyPlayer:IRole
{
public int level{get;set;}
}
public class MyNPC:IRole
{
public int level{get;set;}
}
public class MyMonster:IRole
{
public int level{get;set;}
}

这只介绍了泛型方法的使用。还有泛型类,泛型接口等,在此就不多说了。

用C#开发unity3D游戏用的最多的泛型应该还是泛型集合List<T>之类的,这些就靠平时慢慢熟悉了。

 

使用泛型最大的好处就是代码复用,比如写一段程序要统计"水"的一些属性(信息),如这是什么样的水(矿泉水/自来水/污水.etc),或者水的温度是多少.可以这样写(使用结构体):

  1. public class NewBehaviourScript : MonoBehaviour
  2. {
  3. // Use this for initialization
  4. void Start()
  5. {
  6. Water test = new Water();
  7. test.name = "KuangQuanShui";
  8. test.temperature = 100;
  9. Debug.Log("水的名字: " + test.name + "   水的温度: " + test.temperature);
  10. }
  11. }
  12. public struct Water
  13. {
  14. public string name;//水的名字
  15. public int temperature;//水的温度
  16. }

复制代码

下面是使用泛型来重写上面的这段代码,如下:

  1. public class fanxing : MonoBehaviour
  2. {
  3. // Use this for initialization
  4. void Start()
  5. {
  6. Water<string> test1 = new Water<string>();
  7. test1.info = "KuangQuanShui";//在此传入水的名字是"矿泉水"(可以将"T"看作是string类型)
  8. Water<int> test2 = new Water<int>();
  9. test2.info = 100;//在此传入水的温度是 100(可以将"T"看作是int类型)
  10. Debug.Log("水的名字: " + test1.info + "   水的温度: " + test2.info);
  11. }
  12. }
  13. public class Water<T>
  14. {
  15. public T info;//水的信息(属性)
  16. }

复制代码

上面的"T"可以看作是任意数据类型,(对于为何不使用基类型object及涉及的装箱/拆箱,网上介绍的很详细了,在这就不过多叙述了)通过上面的两段代码可能还看不出泛型有多大的好处,但是想想如果是使用泛型来初始化单例,是不是方便很多.

对于泛型的约束:如果我只允许"T"接收某一个数据类型(比如自定义了一个构造函数,只接收这个类型)如下:

  1. public class fanxing : MonoBehaviour
  2. {
  3. // Use this for initialization
  4. void Start()
  5. {
  6. WaterBase waterInfo = new WaterBase();
  7. Water<WaterBase> test3 = new Water<WaterBase>();//Water<限定只能为WaterBase类型>  可以将"T"看作是WaterBase类型
  8. test3.info = waterInfo;
  9. test3.info.name = "KuangQuanShui";
  10. test3.info.temperature = 100;
  11. Debug.Log("水的名字是: " + test3.info.name + "   水的温度是: " + test3.info.temperature);
  12. }
  13. }
  14. public class Water<T> where T : WaterBase
  15. {
  16. public T info;//水的信息(属性) 可看作"T"的类型是WaterBase
  17. }
  18. public class WaterBase
  19. {
  20. public string name;
  21. public int temperature;
  22. }

复制代码

泛型的约束,官网规定如下:

如果是多个占位符的泛型(两个),示例代码如下:

  1. public class fanxing : MonoBehaviour
  2. {
  3. // Use this for initialization
  4. void Start()
  5. {
  6. //从A产线出来的生产日期是string类型的"20130610",水是矿泉水,温度是20,
  7. Water<string, WaterBase> test1 = new Water<string, WaterBase>();//Water<任意类型,直接收WaterBase类型> 在此"T"相当于string类型
  8. test1.data = "20130610";
  9. test1.info.name = "KuangQuanShui";
  10. test1.info.temperature = 20;
  11. //从B产线出来的生产日期是int类型的20130610,水是纯净水,温度是20,
  12. Water<int, WaterBase> test2 = new Water<int, WaterBase>();//Water<任意类型,直接收WaterBase类型> 在此"T"相当于int类型
  13. test2.data = 20130610;
  14. test2.info.name = "ChunJingShui";
  15. test2.info.temperature = 20;
  16. }
  17. }
  18. public class Water<T, U> where U : WaterBase //限定"U"只能接收WaterBase类型
  19. {
  20. public T data;//出厂日期(可接受int型的20130610,或者string类型的"20130610");
  21. public U info;//水的具体信息(矿泉水/纯净水...温度)
  22. }
  23. public class WaterBase
  24. {
  25. public string name;
  26. public int temperature;
  27. }

复制代码

接下来是泛型的继承,下面分别是一个占位符/多个占位符的继承示例,以及泛型继承的写法:

  1. public class fanxing : MonoBehaviour
  2. {
  3. // Use this for initialization
  4. void Start()
  5. {
  6. TestChild1 test = new TestChild1();
  7. test.data = "KuangQuanShui";
  8. Testchild2 test2 = new Testchild2();
  9. test2.data = 100;
  10. Son1 son1 = new Son1();
  11. son1.data1 = "KuangQuanShui";
  12. son1.data2 = 100;
  13. }
  14. }
  15. #region 一个占位符
  16. public class Test<T>
  17. {
  18. public T data;
  19. }
  20. public class TestChild1 : Test<string> { }
  21. //或者: public class TestChild1<T>: Test<string> { }
  22. //或者: public class TestChild1<T>: Test<T> { }
  23. public class Testchild2 : Test<int> { }
  24. #endregion
  25. #region 两个占位符
  26. public class Fater<T, U>
  27. {
  28. public T data1;
  29. public U data2;
  30. }
  31. public class Son1 : Fater<string, int> { }
  32. //或者: public class Son1<T,U> : Fater<string, int> { }
  33. //或者: public class Son1<T,U> : Fater<T, U> { }

复制代码

下面说一下泛型方法,感觉和泛型差不多(也是允许传入类型任意)就不过多叙述了,示例如下:

  1. public class fanxing : MonoBehaviour
  2. {
  3. // Use this for initialization
  4. void Start()
  5. {
  6. Test test = new Test();
  7. Debug.Log(test.Fanxing<string>("KuangQuanShui"));
  8. Debug.Log(test.Fanxing<int>(100));
  9. }
  10. }
  11. public class Test
  12. {
  13. public T Fanxing<T>(T t)
  14. {
  15. return t;
  16. }
  17. }

复制代码

C#泛型在unity3D中的运用...的更多相关文章

  1. 【Unity3d游戏开发】Unity3D中的3D数学基础---向量

    向量是2D.3D数学研究的标准工具,在3D游戏中向量是基础.因此掌握好向量的一些基本概念以及属性和常用运算方法就显得尤为重要.在本篇博客中,马三就来和大家一起回顾和学习一下Unity3D中那些常用的3 ...

  2. Unity3D中可中途释放的单例

    Unity3D中可中途释放的单例 使用静态类,静态变量的坏处是从程序加载后就一直占用内存,想要释放比较麻烦,可是之前使用的单例,没有提供释放的方法,那是不是也同静态的一样直到程序结束菜释放?那单例的好 ...

  3. 图文详解Unity3D中Material的Tiling和Offset是怎么回事

    图文详解Unity3D中Material的Tiling和Offset是怎么回事 Tiling和Offset概述 Tiling表示UV坐标的缩放倍数,Offset表示UV坐标的起始位置. 这样说当然是隔 ...

  4. unity3d中 刚体(Rigidbody) 碰撞体(Collider) 触发器(Is Trigger)

      刚体(Rigidbody)的官方(摘自Unity3d的官方指导书<Unity4.x从入门到精通>)解释如下: Rigidbody(刚体)组件可使游戏对象在物理系统的控制下来运动,刚体可 ...

  5. Unity3D中Update()与FixedUpdate()的区别

    Unity3D中Update()与FixedUpdate()的区别是什么呢?从字面上理解,它们都是在更新时会被调用,并且会循环的调用.但是Update会在每次渲染新的一帧时,被调用.而FixedUpd ...

  6. Unity3D中C#和js方法相互调用

    通过查找资料,Unity3D中C#和js要相互调用彼此的方法,js文件必须放在"Standard Assets". "Pro Standard Assets" ...

  7. 在unity3d中使用opencv

    1.首先下载opencv2.4.10,解压缩后放在合适的地方,然后根据自己的电脑(32位或64位)选择X86或X64,我的是32位,将“opencv存放路径\build\x86\vc12\bin”加入 ...

  8. Unity3D 中 用quaternion 来对一个坐标点进行旋转的初步体会

    在unity3d中,用四元数来表示旋转,四元数英文名叫quaternion . 比如 transform.rotation 就是一个四元数,其由四个部分组成 Quaternion = (xi + yj ...

  9. Scala 深入浅出实战经典 第42讲:scala 泛型类,泛型函数,泛型在spark中的广泛应用

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

随机推荐

  1. 【C#学习笔记】从粘贴板复制文本

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  2. (转)Spark 算子系列文章

    http://lxw1234.com/archives/2015/07/363.htm Spark算子:RDD基本转换操作(1)–map.flagMap.distinct Spark算子:RDD创建操 ...

  3. 【django】django深入学习笔记

    官网教程 DjangoBook Models 模型 一个类代表一个模型 类中的属性对应了对应数据表的数据 *makemirgations命令生成数据库脚本(还未同步过数据库,第一次要用到) - > ...

  4. Hadoop Hive基础sql语法

     目录 Hive 是基于Hadoop 构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop 分布式文件系统中的数据,可以将结构 化的数据文件映射为一张数据库表,并提供完整的 ...

  5. git常用知识整理

    分布式和集中版本控制的区别 分布式版本控制系统与集中式版本控制系统有何不同呢?首先,分布式版本控制系统根本没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因 ...

  6. C++中关于类型转换的问题讨论

    这里以signed/unsigned char, signed/unsigned short, signed/unsigned int类型为例, 讨论一下基本类型转换的基本原理,这样我们在编程中碰到由 ...

  7. ylbtech-QQ(腾讯)-群

    ylbtech-DatabaseDesgin:ylbtech-QQ(腾讯)-Account-账户模块, Role-角色.权限模块, Message-消息模块, Qzone-QQ空间,Contacts- ...

  8. CH340在STM32实现一键下载电路

    在做基于STM32的多功能MP3播放器的课题时,在程序下载这部分时借鉴了正点原子开发板上的一键下载电路,采用CH340G这款芯片设计. 在画PCB初期原理图部分,对采用CH340G设计的一键下载电路不 ...

  9. OSX学习01之更新头像

    前不久在官网上守株待兔,买了一个官翻版865,其实最想买294的,可是米不足啊——所以,在同时下了865和293的订单,并纠结了一天后,确定了865,剩余的钱够一个Mac mini了,如果不买也可以日 ...

  10. jquery禁用右键单击功能屏蔽F5刷新

    1.禁用右键单击功能$(document).ready(function() { $(document).bind("contextmenu",function(e) { aler ...