2010-10-12 21 views
7

Wpadłem dzisiaj na problem i nie byłem do końca pewien, dlaczego to nie zadziała.Rodzaj obiektu Cast w C#

Poniższy przykładowy kod padnie:

static void Main(string[] args) 
{ 
    int i32 = 10; 
    object obj = i32; 
    long i64 = (long)obj; 
} 

To spowoduje InvalidCastException. Dlaczego to nie działa? Czy C# nie jest wystarczająco inteligentny, aby wiedzieć, że obiekt jest rzeczywiście typu int?

Już wymyśliłem obejście, ale jestem ciekawy, dlaczego powyższy przykładowy kod nie zadziałał w pierwszej kolejności.

Dzięki Tim

+1

Zauważam, że jest to duplikat wielu poprzednich pytań, w tym ostatnio http://stackoverflow.com/questions/3911293 –

Odpowiedz

9

Nie ma obsada dostępny od pudełkowej Int32 do Int64. Dokonywanie pośredni obsady do int powinny działać, ponieważ kompilator jest skłonny do wygenerowania tego:

// verify obj is a boxed int, unbox it, and perform the *statically* 
// known steps necessary to convert an int to a long 
long i64 = (long) ((int)obj); 

ale nie (hipotetycznie) to:

// Find out what type obj *actually* is at run-time and perform 
// the-known-only-at-run-time steps necessary to produce 
// a long from it, involving *type-specific* IL instructions 
long i64 = (long)obj; 

Oto blog post przez Eric Lippert na ten temat.

1

Masz na myśli kompilator lub środowisko wykonawcze?

Środowisko wykonawcze jest wystarczająco inteligentne, więc rzuca InvalidCastException. Jednak kompilator nie może wiedzieć na pewno, jaki typ obiektu jest, ponieważ boxed int.

Boksowanie i rozpakowywanie umożliwia traktowanie typów wartości jako obiektów. Boxing typ wartości pakuje go wewnątrz instancji typu Object reference .

Tak więc od czasu, gdy jest zapakowany jako obiekt, kompilator nie będzie narzekał na to.

Zobacz więcej informacji o boksie i unboxing tutaj:

http://msdn.microsoft.com/en-us/library/yz2be5wk%28VS.80%29.aspx

3

odjazdu this blog post przez Eric Lippert za krwawe szczegóły.

Najważniejsze jest to, że kompilator będzie bardzo powolny (metodą prób i błędów, ponieważ object może być cokolwiek innego), jaki typ został zapakowany i czy można go bezpiecznie rzucać.