2009-04-21 17 views
2

Ich versuche, Code zu schreiben, um Daten aus einem Objekttyp-Feld (stammen aus einem DataSet) in seine Zielfelder (typisiert) zu konvertieren. Ich mache (zumindest versucht) es mit dynamische Konvertierung. Es scheint gut für Strings, Int, DateTime zu funktionieren.C#: Cast ein Objekt zu einem vorzeichenlosen Zahlentyp mit Generics

Aber es funktioniert nicht für unsigned Typen (Ulong, Uint). Unten gibt es einen einfachen Code, der zeigt, was ich tun möchte. Wenn Sie den ul var-Typ von ulong in int ändern, funktioniert es einwandfrei.

Hat jemand eine Ahnung?

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()); 
    } 

} 

Antwort

12

Wie Andrew sagt, das Problem ist, dass man nicht unbox von einem boxed int zu ulong .

zwei Optionen:

1) Box ein ulong statt:

object ul_o = (object) 2UL; 

oder

ulong tmp = 2; 
object ul_o = tmp; 

2) Machen CastIt<T> Verwendung Convert.ChangeType:

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

Dies ist ein bisschen stinkend, aber funktioniert mit Ihrem Beispielcode. Wenn Sie den ersten Weg in Ihrem echten Code verwenden können, wäre das besser.

+0

+1 für Convert.ChangeType - irgendwie habe ich das nie bemerkt – galaktor

0

Die CLR nicht zulässt, dass Sie auf diese Weise werfen, weil Ihr boxed Werttyp in der Tat ist ein int:

object ul_o = (object)2; 

Wenn Sie zu einem ulong zu werfen versuchen, Sie können nicht, weil Sie nicht unbox eine int direkt in eine ulong.

+0

Ich verstehe. Aber warum kann ich es nicht konvertieren, wenn es ein U-Boot ist? Denken Sie, dass es notwendig ist, ein "du" am Ende der Aufgabe zu setzen?wie: Objekt o = 10u; wie Jon vorgeschlagen hat? Cheers – Andres

+1

Sie müssten, weil das dem Compiler einen Hinweis gibt, um ein ulong eher als ein int abzuleiten. –

3

Das liegt daran, dass Ihr ul_o-Objekt eine int, keine vorzeichenlose Zahl ist. Wenn Sie in Ihrer Casting-Funktion sind, werden Castings ausgeführt, während die Zieldaten im Kontext einer object vorliegen. Explizite/implizite Cast-Operatoren (die Sie verwenden müssten) funktionieren nur, wenn Sie das Objekt im Kontext eines Typs haben, der sie implementiert (da diese Operatoren zur Laufzeit dynamisch und nicht dynamisch zur Laufzeit verknüpft sind).

Ist dies wirklich das, was Sie, anstatt nur eine gerade gegossenen tun möchten, verwenden Sie diese:

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

denke ich, was Sie wollen mehr wie ist (nicht getestet, aber richtungs korrigieren) ...

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

Edit: Scooped von Skeet! :)

0

Dies ist nicht wirklich eine Antwort auf Ihre Frage; Ich wollte nur erwähnen, dass, wenn Sie .Net 3.5 verwenden, der Linq to DataSets Code Funktionalität wie das, was Sie implementieren, enthält. Die spezifische Erweiterungsmethode wäre das Feld < T>() in der DataRow-Klasse.