假设我有一个班级MyType
:
sealed class MyType
{
static Type typeReference = typeof(MyType);
//...
}
给出以下代码:
var instance = new MyType();
var type1 = instance.GetType();
var type2 = typeof(MyType);
var type3 = typeReference;
哪些变量分配最有效?
GetType()或typeof()的性能是否足以在静态字段中保存类型?
答案 0 :(得分:20)
typeof(SomeType)
是一个简单的元数据标记查找
GetType()
是虚拟通话;在正面,如果它是一个子类,你将获得派生类型,但在负面,如果它是一个子类,你将得到派生类。如果你明白我的意思。另外,GetType()
需要对结构进行装箱,并且对于可为空的结构不起作用。
如果您在编译时知道类型,请使用typeof()
。
答案 1 :(得分:5)
我会选择type2。它不需要实例化实例来获取类型。它是最具人类可读性的。
答案 2 :(得分:4)
找出答案的唯一方法就是衡量。
“type1”变体不可靠或以任何方式推荐,因为并非所有类型都可以构建。更糟糕的是,它分配了需要作为垃圾收集器的内存并调用了对象构造函数。
对于其余两个选项,在我的机器上,“type3”在调试和释放模式下的速度大约是“type1”的两倍。请记住,这仅适用于我的测试 - 结果可能不适用于其他处理器类型,机器类型,编译器或.NET版本。
var sw = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
var y = typeof(Program).ToString();
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
sw.Restart();
for (int i = 0; i < 10000000; i++)
{
var y = typeReference.ToString();
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
那就是说,这个问题有点令人担忧,这个问题没有明确的要求。如果您发现性能问题,您可能已经对其进行了分析并知道哪个选项更好。这告诉我,这可能是过早的优化 - 你知道这句话,“过早的优化是所有邪恶的根源。”
编程代码不仅仅通过性能来衡量。它还通过正确性,开发人员生产力和可维护性来衡量。在没有强大原因的情况下增加代码的复杂性只会将成本转移到其他地方。现在和未来的应用程序维护者现在已经变成了严重的生产力损失。
我的建议是始终使用“type1”变体。我列出的测量代码不是真实场景。缓存类型到引用变量可能有很多副作用,特别是在.NET加载程序集的方式。它不是仅在需要时加载它们,而是在每次使用应用程序时最终加载它们 - 将理论性能优化转化为非常真实的性能问题。
答案 3 :(得分:3)
他们有点不同。
typeof(MyType)
使用Type
指令获取一个MyType
对象,描述在编译类型中解析的ldtoken
类型。
myInstance.GetType()
获取描述Type
变量的运行时类型的myInstance
对象。
两者都适用于不同的场景。
除非您在编译时知道类型并且可以访问它,否则不能使用typeof(MyType)
。
除非您拥有该类型的实例,否则无法使用myInstance.GetType()
。
typeof(MyType)
总是更有效率,但如果在编译时没有看到类型,则无法使用。您不能使用typeof(MyType)
来学习某个变量的实际运行时类型,因为您不知道该类型。
答案 4 :(得分:-1)
两者基本相同。虽然typeof可用于非实例类,如
typeof(MyClass);
但是
MyClass.GetType();
甚至不会构建,因为你需要有一个类的实例。
长话短说,他们都在不同的背景下做同样的工作。