Question

Consider:

object o = 123456U;
ulong l = (ulong) o; // fails

But this:

object o = 123456U;
ulong l = (ulong) (uint) o; // succeeds

The real issue I have is that I'd like to have a function that depending on a parameter type, processes them differently. Such as:

void foo(object o)
{
switch (Type.GetTypeCode(o.GetType()))
   {
      case TypeCode.UInt32:
      case TypeCode.UInt64:
      ulong l = (ulong) o;
      RunUnsignedIntVersion(l);
      break;
      case TypeCode.Int32:
      case TypeCode.Int64:
      long n = (long) o;
      RunSignedVersion(n);
      break;
   }
}

and you can't make the following calls:

foo(123456U);
foo(123456);

I know there are ways to do this using generics. But I'm using .net micro framework and generics are not supported. But any C# 3.0 compiler specific features are supported including anonymous functions.

Edit I'd like to avoid having to handle each type separately. Is there a way this can be done and still have a parameter of object type?

Was it helpful?

Solution

The unbox operations support only the unbox, not any coercion that you might expect.

Whilst this can be frustrating it is worth noting that fixing this would

  1. make unboxing considerably more expensive
  2. possibly complicate the language due to nasty edge cases on method overload selection

Amongst others, for some in depth explanation, Eric Lippert is, as ever, most instructive

If you care about performance the only effective way to do this is (as Jimmy points out)

case TypeCode.Int32:
    RunSignedVersion((int) o);
    break;
case TypeCode.Int64:
    long n = (long) o;
    RunSignedVersion(n);
    break;

This seems not too onerous.

If this is too painful then you may make use of Convert.ToInt64 or Convert.ToUInt64() with the associated cost.

void foo(object o)
{
   switch (Type.GetTypeCode(o.GetType()))
   {
      case TypeCode.UInt32:
      case TypeCode.UInt64:
          ulong l = Convert.ToUInt64(o);
          RunUnsignedIntVersion(l);
          break;
      case TypeCode.Int32:
      case TypeCode.Int64:
          long n = Convert.ToInt64(o);
          RunSignedVersion(n);
          break;
   }
}

If Convert is not available here is the rotor source for the relevant methods:

    [CLSCompliant(false)]   
    public static ulong ToUInt64(object value) {
        return value == null? 0: ((IConvertible)value).ToUInt64(null);
    }

    [CLSCompliant(false)]   
    public static long ToInt64(object value) {
        return value == null? 0: ((IConvertible)value).ToInt64(null);
    }

IConvertible is supported as an interface in the compact framework, I would assume this would therefore work but have not tried it.

If you want the MicroFramework then I suggest simply implementing the conversion options on a per type basis is the best you can do. The API is so sparse that there really isn't much else possible. I would also suggest that anything based on boxing is risky since this is a significant allocation overhead in a very memory constrained environment.

If you are trying to implement a string.Format() alike have you considered System.Ext.Text.StringBuilder.AppendFormat followed by a ToString?

OTHER TIPS

  case TypeCode.Int32:
    RunSignedVersion((int) o);
    break;
  case TypeCode.Int64:
    long n = (long) o;
    RunSignedVersion(n);
    break;

the reason you can't unbox as int is because unboxing and casting are two different operations that happen to share the same operator.

This is because you can only unbox to the same type that was originally boxed (or to the nullable version of that type).

For example, a boxed byte can only be unboxed to byte or byte?, a boxed int can only be unboxed to int or int?, a boxed long can only be unboxed to long or long? etc etc.

You could create an extension method like that :

public static class ConversionExtensions
{
    public static ulong ToUInt64(this object value)
    {
        return ((IConvertible)value).ToUInt64();
    }
}

You could then use it as follows :

object o = 123456U;
ulong l = o.ToUInt64();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top