Unity中的泛型单例的使用

思考并回答以下问题:

通常情况下,在没有泛型单例这个概念之前,我们如果需要让一个类形成一个单例,通常情况下就会有以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class SceneStateManager
{
private static SceneStateManager _instance; // 私有化构造器

public static SceneStateManager GetInstance() // 能被类调用并且返回类类型的方法GetInstance()
{
if(_instance == null)
{
_instance = new SceneStateManager();
}
return _instance;
}
}

然后我们在另外的类中通过SceneStateManager.GetInstance()就得到了SceneStateManager这样一个类中唯一的对象—对象_instance。如果是这样,在开发过程中,每次你想生成一个单例类,都需要重复以上代码过程,有10个单例类,每个类都要这样写,这样很麻烦。我们引入泛型的概念,写一个抽象类的脚本。其他的类只要继承这个类,就可以自动形成一个单例。

既然这样,我们反过来彻底研究一下泛型以及泛型的具体应用。

我们都知道在ArrayList这样的集合中,是对类型object进行操作的,也就是说任何数据类型被添加到ArrayList中都会变成object类型,这就是我们之所以能在ArrayList进行任何数据类型添加的原因。如下代码所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace GenericDemo
{
class Program
{
static void Main(string[] args)
{
ArrayList al = new ArrayList();
al.Add("小明");
al.Add("小刚");
al.Add(12);
al.Add(15.6f);
}
}
}

但是,当我们进行运用的时候会遇到一些问题,如有以下情况:

1
2


出现上面的原因是向集合中添加元素之后,string类型会自动提升为object,而object类型中是没有Length这样的属性的。遇到这样的情况,就需要强制转换了。如下:

1
2


但是上面的例子当中如果我们用泛型List就会不一样了

1
2


以上我们就是使用泛型,在定义List的时候,其中T表示泛型。

常见的集合一般分为泛型集合和非泛型集合。

其中System.Collections命名空间中的集合都是非泛型的,System.Collections.Generic命名空间中的都是泛型集合。泛型是.Net Framework 2.0后出现的一种类型安全的机制。泛型出现的问题转移到编译时期。避免了装箱拆箱的麻烦。

泛型接口的使用

泛型参数的约束

在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制。如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误。这些限制称为约束。约束是使用 where 上下文关键字指定的。下表列出了六种类型的约束:

where T: struct
类型参数必须是值类型。可以指定除 Nullable 以外的任何值类型。有关更多信息,请参见使用可以为 null 的类型(C# 编程指南)。
where T : class
类型参数必须是引用类型;这一点也适用于任何类、接口、委托或数组类型。
where T:new()
类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时,new() 约束必须最后指定。
where T:<基类名>
类型参数必须是指定的基类或派生自指定的基类。
where T:<接口名称>
类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。
where T:U
为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。

到这里,基本的泛型概念和基本运用讲完了,接下来是重点:泛型单例的使用,在这里,我还是采取脚本代码逐条分析的方法进行介绍何为泛型单例:

1
2


1
2


这样ControlUIManager就可以成为一个单例。

0%