将一个对象转换为相同类型及其对性能的影响

3

关于将对象转换为相同类型的性能问题(一开始可能听起来很奇怪,但让我放在上下文中)

public T Get<T>(string key) where T : class
{
     var objToReturn = (T)_cache[key];
     if (objToReturn != null)
     {
         return objToReturn;
     }
     return null;
}

上面的代码片段是尝试从调用方强类型定义的 "CacheObject" 中获取一个类型为 "T" 的对象。
由于对象的类型是强类型定义的,因此我想知道以下行的含义:
var objToReturn = (T)_chache[key];

这个操作会触发将缓存中的一个实例转换成另一个实例并返回吗?还是类型相同,强制转换被忽略了?
我问这个问题是因为在后面的开发中,强制转换会对获取派生类型非常有用,但我不想在早期培养一个潜在的重大性能问题。
请您给予思考,谢谢。

3
根据您的方法实现,它可以重构为一行代码:return _cache[key] as T; - Andreas Grech
@AndreasGrech:绝对不是,因为可能会出现异常情况-请看我在答案中对您评论的回复。 - Jon Skeet
1个回答

5
你展示的是一个“自然”的引用类型转换。它不会改变对象的任何属性——它只是确保对象是一个适当的类型(要么是你要转换的类型,要么是它的子类)。如果对象的类型不正确,就会抛出异常。不会创建额外的对象或类似这样的东西。
当然它不是完全免费的,但这很少会成为性能瓶颈。
但不清楚你为什么有这段代码:
if (objToReturn != null)
{
    return objToReturn;
}
return null;

为什么不直接使用:

return objToReturn;

那将完全以相同的方式运作。然后你的整个方法可以被简化为:

public T Get<T>(string key) where T : class
{
    return (T) _cache[key];
}

注意,您不应该仅仅使用as,除非您真的想让错误类型的值被静默地返回为null。例如:

cache[key] = new object();
string x = cache[key] as string; // x is null
string y = (string) cache[key]; // Exception

1
Jon,鉴于T:class的限制,对于这种情况,使用(T)_cache[key]_cache[key] as T是否有区别? - Andreas Grech
_cache[key] as T 版本不会抛出异常,但 (T)_cache[key] 版本可能会抛出异常。 - John Willemse
@AndreasGrech:是的 - 当面对错误类型的对象时,as表达式将返回null,而强制转换将抛出异常。 - Jon Skeet
@AndreasGrech:将null强制转换不会引发异常,但是将错误类型的非空引用强制转换会引发异常。尝试object x = new object(); string y = (string) x; - Jon Skeet
1
@Andreas,我不同意。如果_cache[key]是一个类型不为T的类,或者无法转换为类型T,那么将会发生InvalidCastException异常。然而,使用as关键字,则会返回null - John Willemse
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接