I can cast byte to int without any problems.
byte a = 2;
int b = a; // => unboxing, boxing or conversion?
When I cast byte first to object and then to int I get an InvalidCastException.
byte a = 2;
object b = a; // => boxing?
int c = (int) b; // => unboxing fails?
But I can workaround this problem by using Convert.ToInt32.
byte a = 2;
object b = a; // => boxing?
int c = Convert.ToInt32(b); // => what happens here?
Why do I get an InvalidCastException in the second example?
What does Convert.ToInt32 in the background?
Did I label boxing, unboxing and conversion correctly? / What is the correct term when in the examples where I'm not sure?
Are the conversion operators at play here? Is there an overview about the basic conversion operators of the basic types?
Please don't hesistate to hint me other things I might have gotten wrong or missed.
Why do I get an InvalidCastException in the second example?
Because you specified you want to cast (and at the same time unbox) the type of the (boxed) variable to something else. And there is no built-in, implicit or explicit conversion operator defined, so it fails.
What does Convert.ToInt32 in the background?
This. It uses the IConvertible interface to do the conversion.
Did I label boxing, unboxing and conversion correctly? / What is the correct term when in the examples where I'm not sure?
int b = a; // => conversion
object b = a; // => boxing
int c = (int) b; // => casting fails
int c = Convert.ToInt32(b); // => what happens here: a method call that happens to do a conversion
Are the conversion operators at play here? Is there an overview about the basic conversion operators of the basic types?
Yes, although defined in the CLR.
Why do I get an InvalidCastException in the second example?
You can unbox in origin type only
What does Convert.ToInt32 in the background?
It contains a convertation
Did I label boxing, unboxing and conversion correctly? / What is the correct term when in the examples where I'm not sure?
byte a = 2;
int b = a; // convertation (byte to int)
object b = a; // boxing
int c = (int) b; //unboxing
object b = a; // boxing
int c = Convert.ToInt32(b); // convertation (object to int)
Are the conversion operators at play here? Is there an overview about the basic conversion operators of the basic types?
You can reflect framework code to learn how it works deeper.
should be
object b = a; // => boxing
int c = (int) b; //Un-boxing
Related
I am reading a book to pass the Microsoft Exam 70-483 and I got a little stuck on the following question :
The following code is boxed into object o.
double d = 11.5;
object o = d;
You’re asked to cast object o into int. What option should you use in your code?
int i = (int)o; //Option : A
int i = (int)(double)o; //Option : B
int i = (int)(float)(double)o; //Option : C
int i = (float)o; //Option : D
According to book, true answer is C, but I could not understand why the option b is wrong. When I try to run both of them, results are the same. Is there any difference option B and option C? What are your opinions?
In your given example, option B is totally fine.
Option A: You can't box and unbox different types. This will result in an InvalidCastException.
Option B: Totally fine. o will be unboxed in a double. Afterwards it will be cast (explicit) in an integer.
Option C: Like B, but before casting it into an integer, it will be casted to an float. The Result will stay the same. There is absolutly no need for the cast from double to float. It will always truncate.
But there are edges cases! (See below)
Option D: Can't use implicit cast from float to int. Same as A: InvalidCastException
So why C?
There are cases where rounding a double to an int differs from rounding a float to an int.
See the following answer from supercat
You can reproduce this by the following example:
static void Main(string[] args)
{
double val = 12344321.4999999991;
int a = (int)(float)val;
int b = (int)val;
Console.WriteLine(a);
Console.WriteLine(b);
Console.ReadLine();
}
The output will be:
12344322
12344321
So as you can see, casting to float first, will result in a different outcome.
Keep in mind, that these are edge cases and most likely academic problems.
I wish to know my approach is right or wrong ?
Refer the two statements
Case: #1
List<string> person = new List<string>() {
"Harry"
"Emma"
"Watson"
}
Case: #2
Object person = new List<string>() {
"Harry"
"Emma"
"Watson"
}
Let me know
which statement is boxing and which statement is un-boxing ?
Both statements are equal and identical ???
There is no boxing because List is a reference type:
Boxing is the process of converting a value type to the type object or
to any interface type implemented by this value type
Unboxing extracts the value type from the object. Boxing is implicit;
unboxing is explicit. The concept of boxing and unboxing underlies the
C# unified view of the type system in which a value of any type can be
treated as an object.
Read More : MSDN
This is boxing:
int i = 123;
// The following line boxes i.
object o = i;
This is unboxing:
o = 123;
i = (int)o; // unboxing
None of them.
Boxing and unboxing is a mechanism provided to handle value types with unified type system in .NET.
for example:
int i = 4;
object o = i; //boxing, int is boxed in an object
int j = (int)o; //unboxing, an int is unboxed from an object
From MSDN:
Read more about why we need boxing and unboxing.
There is a special case in boxing of nullable types.
When a nullable type boxes, it boxes as its value or null. You can not have a nullable value boxed.
int? a = 4;
object o = a; //boxing, o is a boxed int now
Console.WriteLine(o.GetType()); //System.Int32
int? b = null;
o = b; //boxing, o is null
Console.WriteLine(o.GetType()); // NullReferenceException
It is not an boxing or unboxing.
Boxing means that you store the value type into the reference type, and the unboxing is the reverse of boxing.
In your examples both List and Object are reference type.You are only playing with references
int i = 123;
// The following line boxes i.
object o = i;
o = 123;
i = (int)o; // unboxing
int -> object boxing
object -> int unboxing
For more see here Boxing and Unboxing
why C# can't implicitly convert a long var to an object var then to ulong?
long a = 0;
Object c = a;
ulong b = (ulong)c; // throw exception here
you can only unbox to the exact same type as was boxed
Object c = a
boxes a which is a long
ulong b = (ulong)c;
tries to unbox c as a ulong but it is a long and hence fails.
ulong b = (ulong)((long)c);
would work since it unboxes c as a long. c being long this will work and you can cast long to ulong
If you box a value type T, you can only unbox it as itself or as a Nullable ( T? ).
Any other cast is invalid.
That's because a cast from object can never be interpreted as a conversion, whereas the is a conversion between long and ulong.
So this is legal:
var c = (long) b;
This is also legal:
var c = (long?) b;
But this is not:
var c = (ulong) b;
To do what you want to, you have to cast twice: the first is only unboxing, and the second is the actual conversion:
var c = (ulong)(long) b;
For further information, see this blog post by Eric Lippert.
All the above result in a loss of data if the value is greater than the maximum value of a long (9,223,372,036,854,775,807).
ulong has a minimum of zero and a maximum of 18,446,744,073,709,551,615.
To convert without this risk use
ulong b = Convert.ToUInt64(c);
Short and simple answer: beacuse long and ulong are not the same type. One is a signed long the other is an unsigned long.
The below code fails at the last assignment:
static void Main(string[] args)
{
int a = 5;
object b = 5;
System.Diagnostics.Debug.Assert( a is int && b is int );
double x = (double)a;
double y = (double)b;
}
If both a and b are int, what is the cause of this error?
This is an extremely frequently asked question. See https://ericlippert.com/2009/03/03/representation-and-identity/ for an explanation.
Snippet:
I get a fair number of questions about the C# cast operator. The most frequent question I get is:
short sss = 123;
object ooo = sss; // Box the short.
int iii = (int) sss; // Perfectly legal.
int jjj = (int) (short) ooo; // Perfectly legal
int kkk = (int) ooo; // Invalid cast exception?! Why?
Why? Because a boxed T can only be unboxed to T. (*) Once it is unboxed, it’s just a value that can be cast as usual, so the double cast works just fine.
(*) Or Nullable<T>.
Unboxing requires the exact type - you can do this instead:
double y = (double)(int)b;
This is one of the rare cases where System.Convert comes in handy. You can use System.Convet.ToDouble(obj) to knock it out if you don't know before hand that it will be int.
Implicit casting is a compile-time operation. It's not possible for b of type object.
a is an int, but b is a reference to an object that is an int - it is what is called a boxed int. They are two different things, hence the different behaviors.
This question already has answers here:
Closed 13 years ago.
Possible Duplicates:
Casting: (NewType) vs. Object as NewType
Why is the C# “as” operator so popular?
Hey,
I know this may be a silly question but this doubt came to me today.
What is the difference between doing
String text = (String) variable;
and
String text = variable as String;
?
A cast can do three things:
Perform a user-defined conversion
Perform an unboxing conversion
Perform a reference conversion
An as operation is almost always a reference conversion, the only exception being unboxing to a nullable type:
object x = "hello";
int? y = x as int?; // y is null afterwards
Then there's the behaviour with conversions which fail at execution time. So the differences are:
Casts performing reference conversions or unboxing will throw InvalidCastException on failure; as will result in the null value of the target type instead
Casts can perform user-defined conversions; as can't
Casts can unbox to non-nullable value types; as can only be used for unboxing if the target type is a nullable value type
as will return null if variable isn't actually of that type (String in this case). The cast will throw an exception.
Here is the link to Eric Lippert's blog on casting in C#. I'd summarize it, but it's pretty short and he'll explain it much better than me.
http://blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx
And here is his post on the cast operator:
http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx
There are a lot of different ways to cast in C#.
This will try to cast the reference to a String reference. If the cast fails, it throws an exception:
string text = (String) variable;
This will try to cast the reference to a String reference. If the cast fails, it will return a null reference to be assigned to the variable:
string text = varible as String;
This will cast a string reference to an object reference, which is a safe casting as String inherits from Object:
object text = (object)"1337";
Casting to a parent class can also be done implicitly:
object text = "1337";
This will box a value inside an object, then unbox it to a plain value again:
int value = 42;
object boxed = (object)value;
int valueAgain = (int)boxed;
The boxing can also be done implicitly:
int value = 42;
object boxed = value;
int valueAgain = (int)boxed;
This will make a widening conversion from byte to int:
byte a = 42;
int b = (int)a;
The same works as an implicit conversion:
byte a = 42;
int b = a;
This will make a narrowing conversion from int to byte, throwing away the overflow:
int a = 512;
byte b = (byte)a; // b now contains 0