2011-11-22 45 views
11

Aşağıdaki kodu için çok garip C# derleyicisi davranış buldum:Garip C# derleyicisi davranış (aşırı yük çözünürlük)

Expected: 0 
    But was: null 

neden anlamak:

var p1 = new SqlParameter("@p", Convert.ToInt32(1)); 
    var p2 = new SqlParameter("@p", 1); 
    Assert.AreEqual(p1.Value, p2.Value); // PASS 

    var x = 0; 
    p1 = new SqlParameter("@p", Convert.ToInt32(x)); 
    p2 = new SqlParameter("@p", x); 
    Assert.AreEqual(p1.Value, p2.Value); // PASS 

    p1 = new SqlParameter("@p", Convert.ToInt32(0)); 
    p2 = new SqlParameter("@p", 0); 
    Assert.AreEqual(p1.Value, p2.Value); // FAIL!? 

son satır assert aşağıdaki iletiyle başarısız sınama başarısız: p2 = new SqlParameter("@p", 0);, SqlParameter(string, SqlDbType) ve diğer durumlarda SqlParameter(string, object) olarak giderilmiştir. Ama neden böyle olduğunu anlamıyorum. Benim için bir hataya benziyor ama C# derleyicisinin bu tür bir hataya sahip olabileceğine inanamıyorum.

Bunun için herhangi bir sebep var mı?

P.S. Enum parametresi ve 0 değeri (SqlDbType enum) ile herhangi bir yöntem aşırı yüklenmesi için bir sorun gibi görünüyor.

cevap

11

Temel olarak, 0 değişmez ondalık tamsayı her enum türleri (Cı 4. spec §6.1.3) örtük olarak dönüştürülebilir, yani derleyici SqlParameter(string, SqlDbType) uygulanabilir bir işlev elemanı olduğunu belirler. Daha sonra, iki aday işlevi üyeleri arasında daha iyi olanı seçmek zorundadır ve üzerinden SqlParameter(string, SqlDbType) seçer, çünkü SqlDbType, object (§7.5.3.2) 'den daha özel bir türüdür. maksimum uyarı düzeyini ayarlarken

Ama bu durumda çok kafa karıştırıcı olduğunu kabul ...

+0

Sadece bir fikir, ne olur? Belki de bu konuda uyarır. – dowhilefor

+0

Yeap, anladım. Sorum şu: neden sadece 0 için çalışıyor? –

+5

@VictorHaydin, çünkü spec öyle diyor ... "Bir örtük numaralandırma dönüşümü, ondalık tamsayı-literal 0'ın herhangi bir enum-türüne ve altta yatan türü enum-tipi olan herhangi bir null türüne dönüştürülmesine izin verir". Şimdi, neden bu şekilde tasarlandığını bilmiyorum ama muhtemelen iyi bir sebep var ... C# takımından birine sorman gerek. –