2017-08-22 37 views
16

İki test yöntemim var. Birincisi iyi çalışıyor. İkincisi bir istisna atmaz, ama gerekir. Neden ikincisi bir istisna alamıyor?C# inline işaretli ifade çalışmıyor

[TestMethod] 
[ExpectedException(typeof(OverflowException))] 
public void LongToInt_OverflowWithCheckedBlock() 
{ 
    checked 
    { 
     int maxValue = 2147483647; 
     long longValue = (maxValue + 1); 
     int intValue = (int)longValue; 
    } 
} 

[TestMethod] 
[ExpectedException(typeof(OverflowException))] 
public void LongToInt_OverflowWithCheckedStatement() 
{ 

    int maxValue = 2147483647; 
    long longValue = (maxValue + 1); 
    int intValue = checked((int)longValue);  // No Exception is thrown, why? 
} 
+9

Bir * Geç dönüşüm * hata var. longValue = maxValue + 1 ', 32 bit tam sayıdaki * ilk * aritmetiği yapar ve sonra 64 bit'e dönüştürür. Bu hatanın en yaygın şekli 'çift yüzde = birkısım/100'dür, ve soru o zaman neden "yüzde yüzüm sıfırdır?" Aritmetik yapmayı planladığınız türe dönüştürmeniz gerekir * önce * aritmetik yaparsınız, * sonra *. –

cevap

25

birincisi atar nedeni ile ikinci bir çünkü karşılaştırmanız biraz kapalı. Eğer check herşey

  • 2 yöntemde long den int için sadece check dökme 1 yöntemde
    • .

    onlar eşit aşağıda gibi onları karşılaştırmak ve ne atarsan:

    private static void MethodA() 
    { 
        int maxValue = 2147483647; 
        long longValue = (maxValue + 1); 
        checked 
        { 
         int intValue = (int) longValue; 
        } 
    } 
    
    private static void MethodB() 
    { 
        int maxValue = 2147483647; 
        long longValue = (maxValue + 1); 
        int intValue = checked((int) longValue); 
    } 
    

    bu hat Bunun nedeni ise: int intValue = checked((int) longValue);, onun bu hat atıyor biri değildir :

    :

    long longValue = (maxValue + 1); 
    

    orada kontrol koymak, onlar atmak hem olacak

    burada atıyor Neden: (maxValue + 1) bir long atamadan o sonra denilen intmaxValue (istisna burada gerçekleşir) ve 1 ekleyerek çünkü

    O atar Sizin castint eğer long eklemeden 1 yapmadan önce o atmaz:

    long longValue = ((long) maxValue + 1); 
    
  • 2

    Bu nedenle, long olarak dönüştürüyorsunuz. Denetlenmeyen (maxValue + 1), long içinde sakladığınız -2147483648 sonuçlarına ve int numaralı dizine geri döndüğünüzde sonuçlara neden olur. Böylece sizin intValue saklar nihai döküm sonrası -2147483648

    yerine aşağıda gibi deneyin ve sonuçlanacaktır içinde OverflowException

    int intValue = checked(maxValue + 1); 
    

    (veya) hatta

    long longValue = checked((maxValue + 1)); 
    
    8

    MSDN document gibi dedi

    kelime açıkça ayrılmaz tipi aritmetik işlemleri ve dönüşüm kontrol taşması etkinleştirmek için kullanılır kontrol etti. beyan blok içinde taşan bir değer olması durumunda

    birinci test yöntemi zaten kontrol edilir.

    enter image description here

    ikinci test yöntemi sadece taşan değeri sadece kod bu hat kontrol edilir.

    enter image description here

    taşan checked ifadesi önce gerçekleşmesi olduğundan

    int intValue = checked((int)longValue); //Checked expression

    , CLR zaten değerini dönüştürdü. Ve bunun değeri int aralığı beri -2147483648 which is legal enter image description here

    fark nedir olduğunu?

    Deney Yöntemi 1: İşaretli blok

    Testi Yöntem 2: İşaretli ifade