2016-10-06 11 views
2

У меня есть этот метод:Casting объект междунар бросает InvalidCastException в C#

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

Когда я использую его я получаю InvalidCastException. Однако, когда я использую Convert.ToInt32(rawDossier[0][0]), он работает отлично. В чем проблема?

+1

Что такое _is_ тип объекта, хранящийся в 'rawDossier [0] [0]'? Если это, например, строка, содержащая допустимое число, 'Convert.ToInt32()' будет работать отлично, но бросок будет, конечно, бросить. –

+0

(отредактировано) Вы не можете распаковать ящик с одним числовым типом в другой числовой тип. Кроме того, как и @ RenéVogt, вы не можете преобразовать ссылку на строку в тип значения с синтаксисом cast. –

+0

Что делает 'rawDossier [0] [0]?. GetType(). ToString() 'дать? –

ответ

6

Проблема заключается в том, что вы не отливатьobject к int, вы пытаетесь Unbox Int.

Объект действительно должен быть int. Это не может быть просто то, что может быть преобразован в int.

Так что разница не в том, что это:

int a = (int)obj; 

Действительно нужно obj быть боксировал int, ничего другого, в то время как это:

int a = Convert.ToInt32(obj); 

выполнит метод ToInt32, который будет пытаться фигуры что действительно происходит и поступает правильно.

«правильная вещь» здесь является обеспечение объект в вопросе реализует IConvertible и вызов IConvertible.ToInt32, как это видно из 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, но это то, что может быть conv erted до int.

2

Я бы предположил, что это связано с тем, что объект в вашем списке не является int.

Convert.ToInt32 будет преобразовывать другие типы не-типа, поэтому работает.

Проверьте, что передается методу.

2

При попытке распаковывать int из object, коробочного значения должно быть int, иначе вы получите исключение, в то время как Convert.ToInt32 использует IConvertible реализации коробочного типа для преобразования значения в целом.

Например, если значение, помещенное в квадрат, является строкой "100", то при распаковке оно выдает исключение, но с использованием Convert.ToInt32, внутренне использует int.Parse.

Boxing and Unboxing (C# Programming Guide)

Попытка распаковывать ссылку на тип несовместимого значения вызывает InvalidCastException.