当对象和类完全相同时,从对象到类的强制转换会失败吗?

本文关键字:对象 转换 失败 | 更新日期: 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%确定oBuilding类型,那么将其声明为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)(你摆脱了objnull的问题)。

通常在"转换"到接口时使用asas不允许强制转换,所以对象必须是正确类型的实现。

这三行代码不应该出错。

然而,由于程序中其他地方的错误或某人错误地调用了函数,可能会出现带着不期望的形参调用函数的情况。

所以,检查一下以确保你得到了你所期望的总是好的