(T)retObject [参数]不能将'retObject [参数]'取消装箱作为'T'

时间:2012-11-05 21:56:51

标签: c# generics wmi

不多说, 这就是问题所在:

    public static T WriteIfNotNull<T>(ManagementObject retObject, string parameter)
    {
        return retObject[parameter] != null ? (T)retObject[parameter] : default(T);
    }

TintretObject[parameter]为对象时,它会中断。奇怪的部分(至少对我而言)是,如果T不是T并且实际上是指定的int,它确实有效。

它表示无法将其投放到T(即使在这种情况下Tint)。

@Edit:@dtb在这里:

Specified cast is not valid. 
(T)(object)retObject[parameter] Cannot unbox 'retObject[parameter]' as a 'T'    int         

价值观:

参数:"ProcessId"

retObject [parameter]:4

默认(T):0

@@编辑:这也是电话

pr.ProcessId = Util.WriteIfNotNull<int>(retObject, "ProcessId");

1 个答案:

答案 0 :(得分:2)

在我看来,发生的事情是retObject[parameter]实际上不是int,而是另一种数字类型(通常为uint进程ID),在这种情况下你会想要使用Convert来实际更改值:

return retObject[parameter] != null 
    ? (T)Convert.ChangeType(retObject[parameter], typeof(T)) 
    : default(T);

简单投射在这里不起作用的原因是因为从object投射到int只有在它实际上是一个盒装int时才有效。您无法在一次操作中执行向下转换和转换投放,因为没有从objectint的转换投射。因此,抛弃object要求您转换为确切类型或确切类型的有效超类型,接口等。

因此,要将盒装uint转换为int,我们必须首先取消装箱int(有问题)或使用其中一种Convert方法更改类型(如上所示)。

Convert.ChangeType()适用于在兼容类型之间进行转换,即使它们已装箱。例如,如果retObject[parameter]返回long,那么这将允许将其转换为T int

我在这个here上有一篇博文,内容更详细,希望这是有道理的。另一个要点是,object的投射是向下投射(没有为object定义转换投射)因此你必须将其强制转换为精确类型(或有效的子类型)。