very subtle bug. can you figure out whats wrong with this? :)
-
object x = 2; byte? i = ((byte?)x) ?? 1; First, without throwing this into vs.net. See if you can figure out what is wrong with this expression. Second, it SHOULD exhibit the same behavior if x = null; But it doesn't. Compiler bug maybe?
-
object x = 2; byte? i = ((byte?)x) ?? 1; First, without throwing this into vs.net. See if you can figure out what is wrong with this expression. Second, it SHOULD exhibit the same behavior if x = null; But it doesn't. Compiler bug maybe?
Makes sense to me. What problem do you have?
-
object x = 2; byte? i = ((byte?)x) ?? 1; First, without throwing this into vs.net. See if you can figure out what is wrong with this expression. Second, it SHOULD exhibit the same behavior if x = null; But it doesn't. Compiler bug maybe?
object x = 2;
implies x as an int32, but then why doesn't that work whenint x = 2;
does? also,object x = (byte)2;
works butobject x = (int)2;
doesn't!"An eye for an eye only ends up making the whole world blind"
-
object x = 2;
implies x as an int32, but then why doesn't that work whenint x = 2;
does? also,object x = (byte)2;
works butobject x = (int)2;
doesn't!"An eye for an eye only ends up making the whole world blind"
close! the (byte?) overrides the int implication on the 2 though. However, you are right about an implied int as the problem. And this is where it gets a bit strange. When the expression evalutates without the ?? (becuase x=2 is not null) then it throws an exception and complains about the fact that the 1 is an implied int (even though its not used). The part that seems like a compiler bug to me is that when you set x=null and the expression evaluates with the 1 being used, it treats the 1 not as an int but as a byte?. bug?
-
close! the (byte?) overrides the int implication on the 2 though. However, you are right about an implied int as the problem. And this is where it gets a bit strange. When the expression evalutates without the ?? (becuase x=2 is not null) then it throws an exception and complains about the fact that the 1 is an implied int (even though its not used). The part that seems like a compiler bug to me is that when you set x=null and the expression evaluates with the 1 being used, it treats the 1 not as an int but as a byte?. bug?
No, it's simply that you need an explicit cast from
object
toint
before you can cast the2
tobyte
and thereafter tobyte?
. You don't need an explicit cast fromnull
tobyte?
. And doesn't the cast of the1
fromint
tobyte
happen at compile-time? -
object x = 2; byte? i = ((byte?)x) ?? 1; First, without throwing this into vs.net. See if you can figure out what is wrong with this expression. Second, it SHOULD exhibit the same behavior if x = null; But it doesn't. Compiler bug maybe?
This is not a compiler bug. It's just that C# has a confusing syntax for casts. "(X)a" can mean one of three different things: unboxing, a conversion, or a cast. C# uses the same syntax for all of them, though there are important differences, and you are running into one of then. Leaving away the nullables:
object x = 2;
byte b = (byte)x; // crashes - "object->byte" is unboxing, but "int->byte" is a conversion
byte b = (byte)(int)x; // worksWith nullables, it's really the same. Only the value "null" is special: there is no 'boxed null', instead, a simple null reference is used. And the null reference can be 'unboxed' to any nullable type.
int? a = null;
object b = a; // results in b==null, the type 'int?' is lost
DateTime? c = (DateTime?)b; // valid -
close! the (byte?) overrides the int implication on the 2 though. However, you are right about an implied int as the problem. And this is where it gets a bit strange. When the expression evalutates without the ?? (becuase x=2 is not null) then it throws an exception and complains about the fact that the 1 is an implied int (even though its not used). The part that seems like a compiler bug to me is that when you set x=null and the expression evaluates with the 1 being used, it treats the 1 not as an int but as a byte?. bug?
Allen Anderson wrote:
the expression evaluates with the 1 being used, it treats the 1 not as an int but as a byte?. bug?
No.
byte b = 1;
Although '1' is an int, it's perfectly valid to assign it to a byte variable. This is a conversion from byte to int, and for compile-time constants this conversion is implicit. The problem on the left side of the ?? is just that a cast that does unboxing cannot do a conversion at the same time. The right side does not do any unboxing, so there conversions are valid.
-
This is not a compiler bug. It's just that C# has a confusing syntax for casts. "(X)a" can mean one of three different things: unboxing, a conversion, or a cast. C# uses the same syntax for all of them, though there are important differences, and you are running into one of then. Leaving away the nullables:
object x = 2;
byte b = (byte)x; // crashes - "object->byte" is unboxing, but "int->byte" is a conversion
byte b = (byte)(int)x; // worksWith nullables, it's really the same. Only the value "null" is special: there is no 'boxed null', instead, a simple null reference is used. And the null reference can be 'unboxed' to any nullable type.
int? a = null;
object b = a; // results in b==null, the type 'int?' is lost
DateTime? c = (DateTime?)b; // validThat's probably why the Convert class exists. Call Convert.ToByte(object), and it should work even if the object is a boxed Int32. And it's not that confusing. (Actually, the cast thing isn't confusing either - it's just not obvious that cast syntax not necessarily performs a cast :-D ).
-
object x = 2; byte? i = ((byte?)x) ?? 1; First, without throwing this into vs.net. See if you can figure out what is wrong with this expression. Second, it SHOULD exhibit the same behavior if x = null; But it doesn't. Compiler bug maybe?
Without specifying the type, the C# compiler will turn 2 into an Int32. It will box the int into the object x. You them attempt to unbox the int into a Nullable. This won't work and will throw a runtime exception. You can only unbox a value into its original value.
Religiously blogging on the intarwebs since the early 21st century: Kineti L'Tziyon Judah Himango