当对象和类完全相同时,从对象到类的强制转换会失败吗?
本文关键字:对象 转换 失败 | 更新日期: 2023-09-27 18:05:37
如果我有以下代码
object o = new Building(4, "something");
我尝试下面的
if(o.GetType() == typeof(Building))
Building buildingCast = o as Building;
会出什么问题?我想确保buildingCast
在有问题的强制转换中永远不会为空。有没有可能会失败呢?甚至是一些晦涩难懂的东西?
我问这个问题的原因是我正在清理一个测试项目,我试图清除多余的代码。检查buildingCast
是否可能为空…
if(buildingCast == null)
etc
…但是我们无法到达if语句中的代码
不要为了重构而重构。如果在
行中有以下代码行object o = new Building(4, "something");
Building c = o as Building;
那就把它改成
Building o = new Building(4, "something");
但是如果你有类似
的东西public void SomeMethod(object o)
{
//you absolutely need a sanity check here
Building c = o as Building;
if( c == null )
{
//throw exception perhaps
}
//this can also be rewritten as
Building b = null;
if(o != null && o is Building)
b = (Building)o;
else
//throw exception or log..etc
}
如果您尝试执行以下
if(o.GetType == typeof(Building))
Building buildingCast = o as Building;
那么你就创造了更多的冗余实际上这会使代码变得更不容易读,你必须做一些像
这样的事情Building buildingCast = null; //to be able to use outside the if
if(o.GetType() == typeof(Building))
buildingCast = o as Building;
//you still end up with a null here if cast fails.
//this is the EXACT procedure of the 'as' operator anyway
//which does
Building buildingCast = o is Building ? (Building)o : (Building)null;
. .当然,如果您通过事先检查绝对肯定类型是相同的,那么强制转换永远不会失败。
Building buildingCast = o as Building;
通常,您在转换类o
时看到这种代码,而不知道它是否是正确的类型(并且能够转换为Building
)或o
是否为空。
然后,您通常会看到一个空检查后记。
如果你在上面看到:
Building b = new Building(4, "something");
object o = new Building(4, "something");
那么,as
是冗余的。
但是,如果o
是从系统的其他部分传入的,则永远无法确定,因此需要检查
如果o
的实际类型可分配给Building
,那么这将工作。如果实际类型不兼容,您将得到null
作为结果。因此,如果o
来自上面的行以外的任何地方,您应该在那里留下复选框。
如果您100%确定o
是Building
类型,那么将其声明为Building
。如果这是不可能的,那么您需要将检查留在代码中,并尽早将其转换为检查。例如,假设您通过反射实例化它,并且您知道类型,那么您应该立即强制转换它。
顺便说一句,通过as
进行类型转换已经为您执行了类型检查。如果该类型不适用,则返回null
。
我通读了答案,似乎没有人真正指出as
不是cast,请查看http://msdn.microsoft.com/en-us/library/vstudio/cscsdfbt.aspx了解更多信息。
引用重要部分:
注意,as操作符只执行引用转换、可空转换和装箱转换。as操作符不能执行其他转换,例如用户定义的转换,这些转换应该通过使用强制转换表达式来执行。
用一点描述性的(但不是100%正确的)术语来说,这意味着as
试图改变指针的类型,并查看是否有可能看到它引用的是另一种类型,但它永远不会尝试调用类型转换操作符,无论是否隐含。从低级的角度来看,这是一个巨大的差异。
我还想建议你看看这里的is
http://msdn.microsoft.com/en-us/library/scekt9xw(v=vs.80).aspx,它基本上是类固醇上的obj.GetType() == typeof(sometype)
(你摆脱了obj
是null
的问题)。
通常在"转换"到接口时使用as
。as
不允许强制转换,所以对象必须是正确类型的实现。
这三行代码不应该出错。
然而,由于程序中其他地方的错误或某人错误地调用了函数,可能会出现带着不期望的形参调用函数的情况。
所以,检查一下以确保你得到了你所期望的总是好的