문제

I've found very strange C# compiler behavior for following code:

    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!?

In last line assert fails with following message:

  Expected: 0
  But was:  null

I understand why test fails: p2 = new SqlParameter("@p", 0); is resolved as SqlParameter(string, SqlDbType) and for other cases as SqlParameter(string, object). But I don't understand why this happens. For me it looks like a bug, but I can't believe that C# compiler could have such kind of bug.

Any reasons for this?

P.S. It seems to be a problem for any method overload with enum parameter and 0 value (SqlDbType is enum).

도움이 되었습니까?

해결책

Basically, the decimal integer literal 0 is implicitly convertible to all enum types (C# 4 spec §6.1.3), so the compiler determines that SqlParameter(string, SqlDbType) is an applicable function member. Then it has to choose the better between two candidates function members, and it picks SqlParameter(string, SqlDbType) over SqlParameter(string, object), because SqlDbType is a more specific type than object (§7.5.3.2).

But I agree that in that case it's very confusing...

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top