今天在实现单例的时候,通过继承泛型基类,子类型就可以拥有静态 Instance 属性成员,但是当我通过子类类型获取 Instance 对象时,却没有办法获取到,原因是因为反射时,虽然会在继承的基类中进行查找,但是只限于实例成员,对于静态成员是不进行继承查找的。
下面看一下具体的代码。
1 | using System; |
上面代码没有办法正确的获取到 Instance
对象,因为 C# 不会在基类中查找静态成员,因此只能在 Singleton<T>
中进行查找,修改获取方式:
1 | Type closeType = typeof(Singleton<>).MakeGenericType(typeof(T)); |
另外这种方式实现单例,存在一个问题,特别需要注意,还是接着上面的代码:
1 | public class GSubA:SubA{} |
首先解释第二条为什么为 false,虽然看上去都是继承自 Singleton<T>
基类,但是其他是继承自不同的类型,Singleton<T>
叫做开放类型
,当给泛型参数指定具体类型时,就变为闭合类型
,也就是说 C# 会在运行时,创建两个新的类型 Singleton<SubB>
和 Singleton<SubC>
,不同的类型,其静态成员肯定是不同的。
在理解了上面的解释之后,在看第一条就容易理解了,因为 GSubA
和GSubB
都继承自同一类型 SubA
,所以对应的 Instance
成员相同。
总结一下就两点:
- C# 反射静态成员时,不会在继承结构中查找,只能通过使用静态声明类型来获取;
- 泛型类会根据泛型参数不同,生成不同的闭合类型。