从性能的角度来看,我对这个问题很感兴趣。关于对象需要类型转换这一事实,我知道因此您可能会隐式出错。
更新。这个问题是在采访中被问到的。例如,我添加了 2 个类:
class SomeClass<T>
{
private T[] storage;
}
class SomeClass
{
private object[] storage;
}
从性能的角度来看,我对这个问题很感兴趣。关于对象需要类型转换这一事实,我知道因此您可能会隐式出错。
更新。这个问题是在采访中被问到的。例如,我添加了 2 个类:
class SomeClass<T>
{
private T[] storage;
}
class SomeClass
{
private object[] storage;
}
如果您使用值类型,您将获得额外的打包和后续解包开销。
好吧,正如您自己提到的,这种用法不是类型安全的。
.NET 2.0 中引入了泛型集合,正是为了避免这些问题。早期版本使用
ArrayList,大体上是List<object>.更新程序
在您给出的示例中,一切都是一样的:如果
storage将值类型的实例添加到数组中,则会发生打包。泛型代码相对于非泛型代码的优势:
类型安全。当泛型算法应用于特定类型时,编译器和 CLR 理解这一点并确保在算法中只使用与该数据类型兼容的对象。尝试使用不兼容的对象将导致编译时错误或运行时异常。
通过
SomeType<Stream> some = new SomeType<Stream>()在您的变量中声明,storage可以仅存储该类型Stream或其派生对象。验证将在编写代码的阶段进行,即 将立即发出警告,而不是object- 在运行时。为了评估性能,一个非泛化的FCL
ArrayList类库和一个通用的.List方法
Main- 调用两个测试值类型测试:
引用类型测试:
估计操作执行时间的类
试验结果
结论
使用 Int32,通用 List 算法比非通用 ArrayList 算法快得多。而且,差异巨大:1.6 秒对 11 秒,即快了7 倍!另外,在ArrayList算法中使用一个值类型(Int32)需要大量的装箱操作,因此需要390个垃圾回收程序,而在List算法中只有6个。
引用类型的测试结果并不那么令人印象深刻:垃圾收集的时间和数量在这里大致相同。因此,在这种情况下,通用的 List 算法并没有真正的优势。但是,请记住,使用通用算法可以大大简化代码和编译时输入。
资料来源: Jeffrey Richter“通过 C# 实现 CLR”