将对象转换为 int 在 C# 中抛出 InvalidCastException

Casting object to int throws InvalidCastException in C#

我有这个方法:

private static Dossier PrepareDossier(List<List<object>> rawDossier)
{
    return new Dossier((int)rawDossier[0][0]);
}

当我使用它时,我得到一个 InvalidCastException。但是,当我使用 Convert.ToInt32(rawDossier[0][0]) 时,它工作得很好。有什么问题?

问题是您没有object转换为int,而是试图拆箱 一个整数。

对象确实必须是一个整数。它不能只是任何可以转换为整数的东西。

所以区别在于:

int a = (int)obj;

确实需要 obj 才能成为盒装 int,没有别的,而这个:

int a = Convert.ToInt32(obj);

将执行 ToInt32 方法,该方法将尝试找出真正发生的事情并做正确的事情。

这里的"right thing"是为了保证对象实现IConvertible and calling IConvertible.ToInt32, as is evident from the reference source:

public static int ToInt32(object value) {
    return value == null? 0: ((IConvertible)value).ToInt32(null);
}

您可以在try roslyn看到开箱:

IL_0007: unbox.any [mscorlib]System.Int32

结论:您要拆箱的对象不是 int,但它是可以转换为 int 的东西。

我猜这是因为您列表中的对象不是整数。

Convert.ToInt32 将转换其他非 int 类型,因此有效。

检查传入方法的内容。

当您尝试从 object 中拆箱 int 时,装箱的值应该是 int,否则您将收到异常,而 Convert.ToInt32 使用 IConvertible 将值转换为 int 的装箱类型的实现。

例如,如果装箱的值是字符串 "100",拆箱会抛出异常,但使用 Convert.ToInt32,内部使用 int.Parse.

Boxing and Unboxing (C# Programming Guide)

Attempting to unbox a reference to an incompatible value type causes an InvalidCastException.