Object to decimal casting can't be implemented [duplicate] - c#

This question already has answers here:
Cast object to decimal? (nullable decimal)
(6 answers)
Closed 9 years ago.
I try to cast from Object type to decimal:
Object obj = new Object();
obj = 10;
decimal dec = (decimal)obj;
but in this row decimal dec = (decimal)obj , I get this Exception:
Specified cast is not valid.
Any idea why this unboxing can't be implemented?
Thank you in advance.

which is why you have Convert.ToDecimal() boxing and unboxing can only happen between same types.
10 literal is represented in C# compiler as an System.Int32(correct me if I am wrong people) and hence unboxing of this to a decimal will result in error

You can only unbox a value type to its original type or the nullable equivalent version of that type.
For the reason behind this read this Eric Lippert's

When you write obj = 10;, object has value of type int.
Try this:
Object obj = new Object();
obj = 10M;
decimal dec = (decimal)obj;
or this:
Object obj = new Object();
obj = 10;
decimal dec = (decimal)(int)obj;
You should read Boxing and Unboxing article on msdn.
For the unboxing of value types to succeed at run time, the item being
unboxed must be a reference to an object that was previously created
by boxing an instance of that value type. Attempting to unbox null
causes a NullReferenceException. Attempting to unbox a reference to an
incompatible value type causes an InvalidCastException.

Related

Boxing and UnBoxing from List to Object in C#

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

Boxing and unboxing is also casting?

When we convert the data types between primitive data types it is called as data type casting.
But when convert between ValueType and ReferenceType we call it as boxing and unboxing.
Can boxing and unboxing also be called casting?
Boxing is just wrapping a value type in an object hull, essentially. It doesn't actually involve a type conversion as, say, (int)3.14 does. Even though they both use the cast operator.
C# Type System contains three Types , they are Value Types , Reference Types and Pointer Types. C# allows us to convert a Value Type to a Reference Type, and back again to Value Types . The operation of Converting a Value Type to a Reference Type is called Boxing and the reverse operation is called Unboxing.
Boxing
int Val = 1;
Object Obj = Val; //Boxing
The first line we created a Value Type Val and assigned a value to Val. The second line , we created an instance of Object Obj and assign the value of Val to Obj. From the above operation (Object Obj = i ) we saw converting a value of a Value Type into a value of a corresponding Reference Type . These types of operation is called Boxing.
UnBoxing
int Val = 1;
Object Obj = Val; //Boxing
int i = (int)Obj; //Unboxing
The first two line shows how to Box a Value Type . The next line (int i = (int) Obj) shows extracts the Value Type from the Object . That is converting a value of a Reference Type into a value of a Value Type. This operation is called UnBoxing.
Boxing and UnBoxing are computationally expensive processes. When a value type is boxed, an entirely new object must be allocated and constructed , also the cast required for UnBoxing is also expensive computationally
Boxing is the process to converting a value type to the type object and unboxing retriveing the value back http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx
Well as casting is to convert one type to another compatible type
Casting: (it's basically about converting instance of one type into another)
int a = (int) 3.14 // from the example above does casting with loosing precision.
double b = a; // casting again (we may write (double) a - gives the same result).
Boxing: (process of copying value type to the heap)
object c = new MyStruct(); // MyStruct = struct.
object d = 1;
object e = (int) 3.14; // here we have actually casting and then boxing.
Unboxing (copying boxed value type back to the stack):
Button f = (MyStruct) c;
int g = (int) d; // it still unboxing however it looks exactly like the line #1 above.
Hope it helps.
Boxing is basically boxing a value type into a anonymous object which later can be unboxed.
int x = 567;
object y = x; //boxing
int z = (int) y; //z will be 123
int x = 567;
object y = (object)x; //explicit boxing (not necessary)
int z = (int) y; //z will be 123
Boxing/Unboxing should not be confused with type casting as while boxing we are just putting a wrapper around a variable. By doing the type casting you are actually changing the type of the variable or object.
Double x = 3.14444;
Integer y = (Integer)x; //(type cast or static cast in c++) changing the type and loosing the original value too in this case.
int x = 567;
object y = (object)x; //explicit boxing (not necessary)
float z = (float) y; //another example of type casting while unboxing
Every non-nullable value type has an associated heap-object type with identical members. Boxing a value type storage location creates a new heap-type instance and copies all the fields from the value-type storage location to the corresponding fields of the new instance. Unboxing a value type copies all the fields from an instance of its corresponding heap-object type to the corresponding fields of a value-type storage location.

Casting a boxed value

Why can't an int that's been boxed be directly cast to double?
object o = 12;
double d = (double)o;
That throw an invalid cast exception. Instead it seems it has to first be cast as an int, and then on to double.
object o = 12;
double d = (double)(int)o;
I'm sure the simple answer is "because that's how boxing works" but I'm hoping someone might shed a bit of light here.
Check out this question from earlier today: Why am I getting InvalidCastException?
Unboxing operations only succeed if the target type is exactly the same as the original type that was boxed, so an exception is thrown. This link that John Leidegren provided explains in detail.
If you don't know the original type at compile-time:
object o = 12;
double d = (double)Convert.ChangeType(o, typeof(double));

C# value type casting: how it works? [duplicate]

This question already has an answer here:
Closed 12 years ago.
Possible Duplicate:
Why does this conversion doesn't work?
Hi,
i discovered a strange behaviour of the framework.
This code throws an exception:
byte a = 1;
object b = a;
Console.WriteLine(b.GetType());
Console.WriteLine((byte)b);
Console.WriteLine((int)(byte)b);
Console.WriteLine(Convert.ToInt32(b));
Console.WriteLine((int)b);
The last line throws a System.InvalidCastException.
I'd like to know what are the mechanism in the framework that make this code illegal.
Is it a problem of boxing/unboxing?!
Yes, boxed value types can only be unboxed to the exact same type.
The variable b is a boxed byte.
When you do (int)(byte)b you're unboxing b back to a byte and then converting that unboxed byte to an int.
When you do (int)b you're attempting to unbox b directly to an int, which is illegal.
Edit...
As Jon mentions in his answer, there are cases where you don't have to unbox to the exact same type. Specifically:
A boxed T can be unboxed to Nullable<T>.
A boxed Nullable<T> can be unboxed to T, assuming that the nullable isn't actually null.
A boxed enum with an underlying type of T can be unboxed to T.
A boxed T can be unboxed to an enum with an underlying type of T.
Eric Lippert has a blog post on this.
Why? Because a boxed T can only be
unboxed to T.
Or Nullable< T >.
When you unbox, it has to be to one of the following:
The exact same type
The nullable form of the exact same type
If it's an enum type value, then you can unbox to the underlying type
If it's an integral type value, you can unbox to an enum which uses that underlying type
Examples:
using System;
class Test
{
enum Foo : short
{
Bar = 1
}
static void Main()
{
short x = 1;
object o = x;
short a = (short) o;
short? b = (short?) o;
Foo c = (Foo) o;
o = Foo.Bar;
short d = (short) o;
}
}
Anything else will give an exception. In particular, you can't unbox to a different type even if there's an implicit conversion from the actual type to your target type, which is what you're trying to do on the last line of your example.
You also can't unbox from an integral value to a nullable form of an enum with the same underlying type (or the reverse situation).
Note that if you box a nullable value type value, the result is either null (if the original value was the null value for the type) or the boxed non-nullable value... there's no such thing as a "boxed nullable value type" if you see what I mean.
Is it a problem of boxing/unboxing?
Yes. bis a boxed byte. So you need to unbox it to a byte first , like in (int)(byte)b

Different Cast Types in C# [duplicate]

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

Categories

Resources