Casting, unboxing, conversion..?
Recently I am learning value types and I am bit confused. Also both casting and unboxing uses the same syntax - (expected type)(object), right? A开发者_运维问答nd what about simple conversion between types, that is casting or just conversion?
int x = (int)2.5; //casting?
object a=x;
int Y=(int)a; //unboxing I think
Random r=new Random();
object X=r;
Random R=(Random)X; // casting
There's a lot of things to consider here, but let's tackle the simplest first:
What is the syntax (type)expression
?
Well, in its basic form, it is considered casting. You cast the expression from one type, to another. That's it.
However, what exactly happens, that depends on the type, and a lot of other things.
If casting a value type to something else, you depend on one of the two types involved to declare a casting operator that handles this. In other words, either the value type need to define a casting operator that can cast to that other type, or that other type need to define a casting operator that can cast from the original type.
What that operator does, is up to the author of that operator. It's a method, so it can do anything.
Casting a value type to some other type gives you a different value, a separate value type, or a new reference type, containing the new data after casting.
Example:
int a = (int)byteValue;
Boxing and unboxing comes into play when you're casting a value type to and from a reference type, typically object
, or one of the interfaces the value type implements.
Example:
object o = intValue; // boxing
int i = (int)o; // unboxing
Boxing also comes into play when casting to an interface. Let's assume that "someValueType" is a struct, which also implements IDisposable:
IDisposable disp = (IDisposable)someValueType; // boxed
Casting a reference type, can do something else as well.
First, you can define the same casting operators that were involved in value types, which means casting one reference type to another can return a wholly new object, containing quite different type of information.
Boxing does not come into play when casting a reference type, unless you cast a reference type back to a value type (see above.)
Example:
string s = (string)myObjectThatCanBeConvertedToAString;
Or, you can just reinterpret the reference, so that you still refer to the same object in question, but you are looking at it through a different pair of type glasses.
Example:
IDisposable disp = (IDisposable)someDisposableObject;
One important restriction on unboxing is that you can only unbox to the exact value-type(or its nullable equivalent) and not to another value-type the original value-type is convertible to.
int myInt = 1;
object x = myInt; // box
int unbox1 = (int)x; // successful unbox
int? unbox2 = (int?)x; // successful unbox
long unbox3 = (long)x; // error. Can't unbox int to long
long unbox4 = (long)(int)x; // works. First it unboxes to int, and then converts to long
Another interesting bit is that a nullable value-type gets boxed as its non nullable type, and can be unboxed as both the nullable and the non nullable type. Since a nullable that has the value null
boxes to the reference null
the information about its type is lost during the boxing.
A cast is one form of conversion, basically.
All the comments in your code are correct.
It's important to note the difference between a reference conversion and other conversions, however. The final conversion you've shown is a reference conversion - it maintains representational identity, so the values of X
and R
are both references to the same object.
Compare this with a double
to int
conversion (changes form significantly) and unboxing (copies the value from inside the box to the variable).
The difference is important for some topics such as generic variance - that only works with reference types because of the reference conversions available. Basically the CLR checks that it all the types are appropriate, and then runs the appropriate code without ever having to perform any actual conversions on the references themselves.
Boxing and Unboxing specifically refer to casting value types to reference types and back again. Check out this link for more Boxing and Unboxing (C# Programming Guide).
Boxing and unboxing is done behind the scenes by compiler. So correct comments would be
int x = (int)2.5; //casting with conversion
object a=x; //casting with boxing
int Y=(int)a; //casting with unboxing
Random r=new Random();
object X=r;
Random R=(Random)X; //casting without unboxing
about casting vs conversion check this question: What is the difference between casting and conversion?
精彩评论