2010-10-17 30 views
34

Bu açık yayınlama neden Specified cast is not valid. istisnasını atıyor?Neden (int) (object) 10m throw "Belirtilen cast geçerli değil" istisnası?

decimal d = 10m; 
object o = d; 
int x = (int)o; 

Ama bu işleri:

object o = d; 

Sen olmadan aralıklı değerler doğrudan döküm olamaz: Bunu yaptığınızda

int x = (int)(decimal)o; 
+1

olası yinelenen [? Ben ondalık olarak bir int Unbox edemez Neden] (http://stackoverflow.com/questions/1085097/why-cant-i: Eğer dönüştürme sınıfını kullanarak çağırmak Hangi -unbox-an-int-bir-ondalık) – nawfal

cevap

59

Kutulu bir değer yalnızca aynı türden bir değişkene kutudan çıkarılabilir. Bu görünüşte garip bir kısıtlama, jeneriklerin bulunabilmesinden önce .NET 1.x'i mümkün kılan çok önemli bir hız optimizasyonu. Bu konuda daha fazla bilgi edinebilirsiniz this answer.

Birden çok döküm kasnağı atlamak zorunda değilsiniz, basit değer türleri IConvertible arabirimini uygular.

 object o = 12m; 
     int ix = Convert.ToInt32(o); 
ait
+0

Çok tatlı! Sabahtan beri kafamı yıkıyordum. – RBT

15

, sen örtülü temel nesneye ondalık d boks ediyoruz ilk olarak, aşağıdaki gibi bir int doğrudan döküm, bu yüzden, aşağıdakileri başarısız:

int x = (int)o; 

Ancak, (orta derecede bir ondalık birinciye döküm) yaparak:

int x = (int)(decimal)o; 

Sen kutusuz ondalık değer döküm sonra ondalık değer, alınırken, yani hedef ilk kutudan çıkarma o konum C# çalıştığı için bir int için çalışır, çünkü C#, ondalıkların intlere dökülmesini destekler.

6

decimal, explicit cast operator için int'a sahiptir. object yapmaz:

decimal d = 10m; 
object o = d; 
int x = (int)d; // OK, calls decimal.explicit operator int(d). 
int y = (int)o; // Invalid cast. 
3

Burada ne düşünmek gerektiğini boks ve unboxing dönüşüm tam olarak bir tür değildir. Nesne tipini ilk ondalık türünde "etrafında" yazarsınız. Bu nedenle, önce bir tamsayıya dönüştürmeden önce nesnenin kutusundan çıkarılması gerekir.

İlgili konular