Andres
Andres

Reputation: 3414

C#: Cast a object to a unsigned number type using Generics

I'm trying to write some code to convert data from a object type field (come from a DataSet) into it's destination (typed) fields. I'm doing (trying at least) it using dynamic conversion. It seems to work fine for strings, int, DateTime.

But it doesn't work for unsigned types (ulong, uint). Below there's a simple code that shows what I want to do. If you change the ul var type from ulong to int, it works fine.

Does anybody have a clue?

public class console
{

    public static void CastIt<T>(object value, out T target)
    {
        target = (T) value;
    }

    public static void Main()
    {
        ulong ul;
        string str;
        int i;
        DateTime dt;

        object ul_o = (object) 2;
        object str_o = (object) "This is a string";
        object i_o = (object)1;
        object dt_o = (object) DateTime.Now;

        Console.WriteLine("Cast");

        CastIt(ul_o, out ul);
        CastIt(str_o, out str);
        CastIt(i_o, out i);
        CastIt(dt_o, out dt);

        Console.WriteLine(ul);
        Console.WriteLine(str);
        Console.WriteLine(i);
        Console.WriteLine(dt.ToString());
    }

}

Upvotes: 3

Views: 4321

Answers (5)

Chris Shaffer
Chris Shaffer

Reputation: 32575

This is not really an answer to your question; Just wanted to mention that if you are using .Net 3.5, the Linq to DataSets code includes functionality like what you are implementing. The specific extension method would be Field<T>() on the DataRow class.

Upvotes: 0

JP Alioto
JP Alioto

Reputation: 45127

I think what you want is more like (untested, but directionally correct) ...

public static void CastIt<T>( object value ) where T : IConvertable
{
  return ( T )Convert.ChangeType( value , typeof( T ) );
}

Edit: Scooped by Skeet! :)

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1502206

As Andrew says, the problem is that you can't unbox from a boxed int to ulong.

Two options:

1) Box a ulong instead:

object ul_o = (object) 2UL;

or

ulong tmp = 2;
object ul_o = tmp;

2) Make CastIt<T> use Convert.ChangeType:

public static void CastIt<T>(object value, out T target)
{
    target = (T) Convert.ChangeType(value, typeof(T));
}

This is a bit smelly, but works with your example code. If you can use the first way in your real code, that would be better.

Upvotes: 12

Adam Robinson
Adam Robinson

Reputation: 185663

That's because your ul_o object is an int, not an unsigned number. When you're in your casting function, you're casting while having the target data in the context of an object. Explicit/implicit cast operators (which is what you'd need to be using) only work when you have the object in the context of a type that implements them (since those operators are statically linked at compile time rather than dynamically at runtime).

If this is really what you want to do, instead of just a straight cast, use this:

target = (T)Convert.ChangeType(value, typeof(T));

Upvotes: 3

Andrew Hare
Andrew Hare

Reputation: 351566

The CLR does not allow you to cast this way because your boxed value type is in fact an int:

object ul_o = (object)2;

When you are attempting to cast to a ulong you cannot because you cannot unbox an int directly into a ulong.

Upvotes: 0

Related Questions