不多说, 这就是问题所在:
public static T WriteIfNotNull<T>(ManagementObject retObject, string parameter)
{
return retObject[parameter] != null ? (T)retObject[parameter] : default(T);
}
当T
为int
且retObject[parameter]
为对象时,它会中断。奇怪的部分(至少对我而言)是,如果T
不是T
并且实际上是指定的int,它确实有效。
它表示无法将其投放到T
(即使在这种情况下T
为int
)。
@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");
答案 0 :(得分:2)
在我看来,发生的事情是retObject[parameter]
实际上不是int
,而是另一种数字类型(通常为uint
进程ID),在这种情况下你会想要使用Convert
来实际更改值:
return retObject[parameter] != null
? (T)Convert.ChangeType(retObject[parameter], typeof(T))
: default(T);
简单投射在这里不起作用的原因是因为从object
投射到int
只有在它实际上是一个盒装int
时才有效。您无法在一次操作中执行向下转换和转换投放,因为没有从object
到int
的转换投射。因此,抛弃object
要求您转换为确切类型或确切类型的有效超类型,接口等。
因此,要将盒装uint
转换为int
,我们必须首先取消装箱int
(有问题)或使用其中一种Convert
方法更改类型(如上所示)。
Convert.ChangeType()
适用于在兼容类型之间进行转换,即使它们已装箱。例如,如果retObject[parameter]
返回long
,那么这将允许将其转换为T
int
。
我在这个here上有一篇博文,内容更详细,希望这是有道理的。另一个要点是,object
的投射是向下投射(没有为object
定义转换投射)因此你必须将其强制转换为精确类型(或有效的子类型)。