在Generics CLR Via C#v3章节中,Jeffrey Richter说下面TypeList<T>
有两个优点
超过List<Object>
,但是如何实现编译时类型安全?
//A single instance of TypeList could hold different types.
using System;
using System.Collections.Generic;
using System.Text;
namespace MyNamespace
{
namespace Generics
{
class Node
{
private Node next_;
public Node(Node next) {
next_ = next;
}
public Node getNext() {
return next_;
}
}
internal sealed class TypeList<T> :Node
{
T data_;
public T getData() {
return data_;
}
public TypeList(T data, Node next):base(next) {
data_ = data;
}
public TypeList(T data):this(data,null) {
}
public override String ToString()
{
return data_.ToString() + (base.getNext() != null ? base.getNext().ToString() : string.Empty);
}
}
class Dummmy:Object
{
public override String ToString() {
return "Dummytype".ToString();
}
}
class Program
{
static void Main(string[] args)
{
Dummmy dummy = new Dummmy();
Node list = new TypeList<int>(12);
list = new TypeList<Double>(12.5121, list);
list = new TypeList<Dummmy>(dummy, list);
Double a = ((TypeList<Double>)list).getData();//Fails at runTime invalid cast exception
Console.WriteLine(list.ToString());
Console.Write("sds");
}
}
}
}
答案 0 :(得分:5)
编译类型安全意味着您将在编译时获得有关无效类型使用的所有错误,但不会在运行时时获得。
例如,以下代码会导致编译时错误:
TypeList<int> list = new TypeList<int>(1);
string someString = list.getData(); // compile error here
如果您使用TypeList<object>
,则没有编译时安全性,因为编译器不会报告错误,您会收到运行时错误:
TypeList<object> list = new TypeList<object>(1);
string someString = (string)list.getData(); // runtime error here
答案 1 :(得分:1)
这意味着因为TypeList是一个泛型类,所以在编译时可以知道所使用的类型是什么,它可以避免在运行时将所需类型转换为正在使用的实际类型。
答案 2 :(得分:1)
因为TypeList是通用的。实际的T类型是在编译时定义的,因此任何类型的检查都是在编译时完成的。
答案 3 :(得分:1)
Double a = ((TypeList<Double>)list).getData(); //Fails at runTime
这是你问题的症结所在。 list 变量实际上是TypeList<Dummy>
。编译器知道这一点,并且在您编写
Double a = list.getData();
那里的编译时类型安全。但你应用了一个演员来让它编译。编译器根据他的假设工作:“他知道他在做什么,他使用了演员”并让它通过。当然不行,现在它在运行时爆炸。
你可以争辩说“但编译器知道演员无法正常工作,这不是什么类型的安全性?”。不,演员阵容非常强大,它让你覆盖编译器知道什么。这个特定的例子不是很好,但你必须使用强制转换将基类引用转换为派生类引用。很常见。演员的力量使其变得危险。泛型的最大优点是您不需要使用它们。
答案 4 :(得分:0)
本文档Design and Implementation of Generics for the .NET Common Language Runtime详细介绍了泛型,以及为实现泛型而做出的权衡。