There are three types of conversions going on here:
Conversion 1 is a reference conversion. The CLR will check that the value of stream
is actually a reference to a MemoryStream
(or subtype) and then simply copy the reference into memoryStream
. No new objects are created or anything like that. Afterwards, both stream
and memoryStream
refer to the same objects. The values of the two variables will be exactly the same in memory.
Conversions 2 and 4 are numeric conversions - they're changing from one numeric form to another. This is basically an FPU type operation. Conversion 2 is explicit (because it may lose information) whereas conversion 4 is implicit, but fundamentally they're similar in that they're both changing actual representations.
Conversion 3 is an unboxing operation: the CLR checks that the value of k
is a reference to a boxed int (or a compatible type, such as an enum with an underlying type of int
), and copies the value out of that box into l
.
You can see the IL generated for all of this by compiling the code and then using ildasm or Reflector, of course.
Eric Lippert has a blog post about all of this which you may find useful.