Thursday, January 25, 2007
« LINQ | Main | Netgear SPH200D (Skype) »
int? i;
object o;

// this is ok:
if (i.HasValue)
    o = i;
else
    o = DBNull.Value;

// This fails to compile. Error 1 Type of conditional expression cannot be determined
// because there is no implicit conversion between 'int?' and 'System.DBNull'
o = i.HasValue ? i : DBNull.Value;

// these also fail for the same reason
o = i == null ? DBNull.Value : i;
o = i.HasValue ? i : "ABC";

// but these works:
o = i.HasValue ? (object)i : DBNull.Value;
o = i.HasValue ? (object)i : (object)DBNull.Value;
o = i.HasValue ? i : (object)DBNull.Value;
kick it on DotNetKicks.com   Thursday, January 25, 2007 11:01:10 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [1]  | 
Saturday, July 21, 2007 2:12:18 AM (Pacific Standard Time, UTC-08:00)
That's an interesting point, whose reason I think is partly given to the fact of being in a strongly typed language. As I wrote that sentence I started wondering, so I wrote some test methods and then used ildasm to see the IL that was generated by the methods.
The methods here are followed by their own IL. You can infer from this that there is a subtle difference in the way that the compiler handles the tertiary operator and its supposed analog. Could be a design flaw in the language; on the other hand, comprehending the nature of this problem gives me insight into the incredible complexity of writing an object-oriented language.

cheers,
Tyler

public void a(int? b)
{
object o;
o = b.HasValue ? (object)b : DBNull.Value;
o.ToString();
}
public void c(int? b)
{
object o;
if (b.HasValue)
o = b;
else
o = DBNull.Value;
o.ToString();
}


.method public hidebysig instance void a(valuetype [mscorlib]System.Nullable`1<int32> b) cil managed
{
// Code size 32 (0x20)
.maxstack 2
.locals init ([0] object o)
IL_0000: nop
IL_0001: ldarga.s b
IL_0003: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_0008: brtrue.s IL_0011
IL_000a: ldsfld class [mscorlib]System.DBNull [mscorlib]System.DBNull::Value
IL_000f: br.s IL_0017
IL_0011: ldarg.1
IL_0012: box valuetype [mscorlib]System.Nullable`1<int32>
IL_0017: stloc.0
IL_0018: ldloc.0
IL_0019: callvirt instance string [mscorlib]System.Object::ToString()
IL_001e: pop
IL_001f: ret
} // end of method PopupControl::a

.method public hidebysig instance void c(valuetype [mscorlib]System.Nullable`1<int32> b) cil managed
{
// Code size 38 (0x26)
.maxstack 2
.locals init ([0] object o,
[1] bool CS$4$0000)
IL_0000: nop
IL_0001: ldarga.s b
IL_0003: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_0008: ldc.i4.0
IL_0009: ceq
IL_000b: stloc.1
IL_000c: ldloc.1
IL_000d: brtrue.s IL_0018
IL_000f: ldarg.1
IL_0010: box valuetype [mscorlib]System.Nullable`1<int32>
IL_0015: stloc.0
IL_0016: br.s IL_001e
IL_0018: ldsfld class [mscorlib]System.DBNull [mscorlib]System.DBNull::Value
IL_001d: stloc.0
IL_001e: ldloc.0
IL_001f: callvirt instance string [mscorlib]System.Object::ToString()
IL_0024: pop
IL_0025: ret
} // end of method PopupControl::c

tyler
Name
E-mail
Home page

Comment (Some html is allowed: a@href@title, strike) where the @ means "attribute." For example, you can use <a href="" title=""> or <blockquote cite="Scott">.  

Enter the code shown (prevents robots):

Live Comment Preview