我有一个事件处理程序,如果它与特定类型匹配,则需要确定一个类型并执行代码。最初我们将它转换为一个对象,如果它不是null我们执行代码,加快它我使用反射,它实际上减慢了它,我不明白为什么。
这是一个代码示例
Trace.Write("Starting using Reflection");
if (e.Item.GetType() == typeof(GridDataItem))
{
bool isWatch = Convert.ToBoolean(e.Item.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["IsWatch"]);
if (isWatch)
{
e.Item.Style["Font-Weight"] = "bold";
}
}
Trace.Write("Ending using Reflection");
Trace.Write("Starting using Cast");
GridDataItem gridItem = e.Item as GridDataItem;
if (gridItem !=null)
{
bool isWatch = Convert.ToBoolean(gridItem.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["IsWatch"]);
if (isWatch)
{
gridItem.Style["Font-Weight"] = "bold";
}
}
Trace.Write("Ending using Cast");
这是我得到的跟踪输出
Starting using Reflection 0.79137944962406 0.576538
Ending using Reflection 0.791600842105263 0.000221
Starting using Cast 0.791623353383459 0.000023
Ending using Cast 0.791649308270677 0.000026
Starting using Reflection 0.876253801503759 0.084604
Ending using Reflection 0.87631790075188 0.000064
Starting using Cast 0.87633445112782 0.000017
Ending using Cast 0.87634950075188 0.000015
它并不是很多,但如果我们不得不这么做,它可能会累积起来。
答案 0 :(得分:15)
反射很慢,因为您正在查询程序集的元数据,而转换只是更改了您引用的对象的类型。
程序集的元数据是一个有用的信息存储,但该信息最好在编译时而不是在执行时使用。编译器使用该元数据进行静态类型检查(以及其他内容)。您正在使用相同的元数据在执行时查找类型信息(如果您没有其他选择,这很好),这比铸造要慢得多。
答案 1 :(得分:3)
反射必须在运行时进行并确定对象在运行时具有的属性等。转换告诉应用程序它应该期望一个对象具有X属性并且应该以某种方式运行。
答案 2 :(得分:2)
Casting告诉运行时您“知道”特定对象的类型。虽然您可能错了,但运行时认为您并且没有花费额外的时间来检查程序集的元数据。
答案 3 :(得分:1)
为什么不使用is operator?我认为它更具可读性,因为你没有明确的演员,然后检查。它只是检查变量的类型是否正确。
if (e.Item is GridDataItem)
{
bool isWatch = Convert.ToBoolean(e.Item.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["IsWatch"]);
if (isWatch)
{
e.Item.Style["Font-Weight"] = "bold";
}
}
答案 4 :(得分:1)
强制转换可以在运行时内进行整数比较,但反射涉及完整的方法调用。
答案 5 :(得分:0)
如果您可以使用常规代码获得相同的结果,那么我可以直接回答最佳实践部分永远不会使用反射。
在优化代码时,通常最好估计优化所花费的时间将带来最大的性能提升。在语言中本地重新实现运算符很少会成为该列表的顶部