129 Stimmen

Objekt in T gießen

Ich analysiere eine XML-Datei mit dem XmlReader Klasse in .NET und ich dachte, es wäre klug, eine generische Parse-Funktion zu schreiben, um verschiedene Attribute generisch zu lesen. Ich kam mit der folgenden Funktion:

private static T ReadData<T>(XmlReader reader, string value)
{
    reader.MoveToAttribute(value);
    object readData = reader.ReadContentAsObject();
    return (T)readData;
}

Wie ich feststellte, funktioniert dies nicht ganz so, wie ich es geplant habe; es wirft einen Fehler mit primitiven Typen wie int ou double da ein Cast nicht von einer string zu einem numerischen Typ. Gibt es eine Möglichkeit, meine Funktion in geänderter Form durchzusetzen?

284voto

Bob Punkte 93584

Prüfen Sie zunächst, ob er gegossen werden kann.

if (readData is T) {
    return (T)readData;
} 
try {
   return (T)Convert.ChangeType(readData, typeof(T));
} 
catch (InvalidCastException) {
   return default(T);
}

20voto

Lasse V. Karlsen Punkte 364542

Haben Sie versucht Convert.ChangeType ?

Wenn die Methode immer eine Zeichenkette zurückgibt, was ich merkwürdig finde, aber das ist nicht der Punkt, dann würde dieser geänderte Code vielleicht das tun, was Sie wollen:

private static T ReadData<T>(XmlReader reader, string value)
{
    reader.MoveToAttribute(value);
    object readData = reader.ReadContentAsObject();
    return (T)Convert.ChangeType(readData, typeof(T));
}

17voto

Sadegh Punkte 6434

Versuchen Sie

if (readData is T)
    return (T)(object)readData;

3voto

Tom Ritter Punkte 97450

Sie könnten verlangen, dass der Typ ein Referenztyp ist:

 private static T ReadData<T>(XmlReader reader, string value) where T : class
 {
     reader.MoveToAttribute(value);
     object readData = reader.ReadContentAsObject();
     return (T)readData;
 }

Und dann eine andere, die Werttypen und TryParse verwendet...

 private static T ReadDataV<T>(XmlReader reader, string value) where T : struct
 {
     reader.MoveToAttribute(value);
     object readData = reader.ReadContentAsObject();
     int outInt;
     if(int.TryParse(readData, out outInt))
        return outInt
     //...
 }

3voto

baretta Punkte 7117

Das eigentliche Problem ist hier die Verwendung von ReadContentAsObject. Leider erfüllt diese Methode nicht die in sie gesetzten Erwartungen. Während sie den am besten geeigneten Typ für den Wert erkennen sollte, gibt sie tatsächlich eine Zeichenkette zurück, egal was es ist (dies kann mit Reflector überprüft werden).

Allerdings, in Ihrem speziellen Fall, Sie wissen bereits den Typ, den Sie wollen, um zu werfen, daher würde ich sagen, Sie sind mit der falschen Methode.

Versuchen Sie es stattdessen mit ReadContentAs, das ist genau das, was Sie brauchen.

private static T ReadData<T>(XmlReader reader, string value)
{
    reader.MoveToAttribute(value);
    object readData = reader.ReadContentAs(typeof(T), null);
    return (T)readData;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X