Why Can't I Unbox an Int as a Decimal

Why can't I unbox an int as a decimal?

You can only unbox a value type to its original type (and the nullable version of that type).

By the way, this is valid (just a shorthand for your two line version):

object i = 4;
decimal d = (decimal)(int)i; // works even w/o decimal as it's a widening conversion

For the reason behind this read this Eric Lippert's blog entry: Representation and Identity

Personally, I categorize things done by cast syntax into four different types of operation (they all have different IL instructions):

  1. Boxing (box IL instruction) and unboxing (unbox IL instruction)
  2. Casting through the inhertiance hierarchy (like dynamic_cast<Type> in C++, uses castclass IL instruction to verify)
  3. Casting between primitive types (like static_cast<Type> in C++, there are plenty of IL instructions for different types of casts between primitive types)
  4. Calling user defined conversion operators (at the IL level they are just method calls to the appropriate op_XXX method).

C#/.NET: Why can't I cast this decimal to an int?

Because there is an explicit conversion defined in the framework from decimal to int. Read this MSDN documentation.

Why can't I cast boxed int to nullable decimal?

A boxed int can only be unboxed to an int. This, however, is legal:

object zero = 0;
decimal? dec = (decimal?)(int)zero;

See MSDN or the ECMA 334 C# spec for details. The key here is the following:

Unboxing is an explicit conversion from the type object to a value type or from an interface type to a value type that implements the interface. An unboxing operation consists of:

  1. Checking the object instance to make sure that it is a boxed value of the given value type.
  2. Copying the value from the instance into the value-type variable.

Edit: This linked article is worth pulling out of the comments. Thanks Rob Kennedy!

Object to decimal casting can't be implemented

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

Can not unbox bigint to long

You have to cast twice:

long? id = (long?) (decimal?) ppwDb.ExecuteScalar(ppwDbCmd);

The first cast will unbox the decimal?. The second cast will do a conversion from decimal? to long?. You cannot skip the first cast because a decimal? cannot be unboxed to a long?.

This assumes that ppwDb.ExecuteScalar(ppwDbCmd) returns object but the actual value returned is a decimal?.

However, I suspect that ppwDb.ExecuteScalar(ppwDbCmd) returns DBNull.Value if the id is null. In that case you will have to do special handling for that value:

object result = ppwDb.ExecuteScalar(ppwDbCmd);
long? id = result != DBNull.Value ? (long?) (decimal) result : null;

C# - Issues with boxing / unboxing / typecasting ints. I don't understand

Unboxing checks the exact type as explained in the documentation.

Unboxing is an explicit conversion from the type object to a value
type or from an interface type to a value type that implements the
interface. An unboxing operation consists of:

  • Checking the object instance to make sure that it is a boxed value of
    the given value type.

  • Copying the value from the instance into the value-type variable.

As you can see the first step is to check that the object instance matches the target type.

Also quote from the documentation:

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.

So to fix this error make sure that the type matches before attempting to unbox:

object thirdTest = Convert.ToInt16(0);
short thirdtest2 = (short)thirdTest;

Unbox a number to double

The simplest way is probably to use Convert.ToDouble. This does the conversion for you, and works with numeric types, strings, and anything else that implements IConvertible (and has a value that can be converted to a double).

public static double Foo(object obj)
{
// you could include a check (IsValueType, or whatever) like you have now,
// but it's not generally necessary, and rejects things like valid strings
return Convert.ToDouble(obj);
}

var is casted to int even when result should be decimal

The literals 7 and 2 both are interpreted by the compiler as int. So the division is an integer division resulting in an int of value 3.

Using the var keyword, the compiler infers the correct type from the expression, leading to number in the first line being of type int.

In the second line, you explicitly declare number as decimal, so the int returned by 7 / 2 is casted to decimal.


If you want the result to be decimal, you should use the correct literal ending with m:

var number = 7/2m;

Why does (int)(object)10m throw Specified cast is not valid exception?

A boxed value can only be unboxed to a variable of the exact same type. This seemingly odd restriction is a very important speed optimization that made .NET 1.x feasible before generics were available. You can read more about it in this answer.

You don't want to jump through the multiple cast hoop, simple value types implement the IConvertible interface. Which you invoke by using the Convert class:

        object o = 12m;
int ix = Convert.ToInt32(o);

LLBLGen Pro Unboxing Error With Decimal Fields

Please post on our support forums (http://www.llblgen.com/tinyforum) so our support team can pick it up.

As you haven't given the version you're using, nor the oracle ADO.NET provider you're using (ODP.NET or MS Oracle), I can't help you further other than giving some general information:

As ODP.NET returns a NUMBER(10, 0) as long, I think you're using MS Oracle. MS Oracle (the .NET oracle provider) returns all NUMBER types as decimal. If you don't want that, use ODP.NET

The cast issue is weird, it should work properly. But as said, please post on our forums as we don't regularly monitor stackoverflow for llblgen related issues. Thanks.



Related Topics



Leave a reply



Submit