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?

2voto

Ricardo Villamil Punkte 4924

Fügen Sie eine "Klassen"-Einschränkung hinzu (oder detaillierter, wie eine Basisklasse oder Schnittstelle Ihrer erwarteten T-Objekte):

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

oder where T : IMyInterface o where T : new() usw.

2voto

ChrisW Punkte 53239

Vermutlich können Sie als Parameter einen Delegaten übergeben, der von String nach T konvertiert.

1voto

genki Punkte 301

Die Antworten werfen eine interessante Frage auf, nämlich was Ihre Funktion im Falle eines Fehlers tun soll.

Vielleicht wäre es sinnvoller, es in Form einer TryParse-Methode zu konstruieren, die versucht, in T zu lesen, aber false zurückgibt, wenn es nicht möglich ist?

    private static bool ReadData<T>(XmlReader reader, string value, out T data)
    {
        bool result = false;
        try
        {
            reader.MoveToAttribute(value);
            object readData = reader.ReadContentAsObject();
            data = readData as T;
            if (data == null)
            {
                // see if we can convert to the requested type
                data = (T)Convert.ChangeType(readData, typeof(T));
            }
            result = (data != null);
        }
        catch (InvalidCastException) { }
        catch (Exception ex)
        {
            // add in any other exception handling here, invalid xml or whatnot
        }
        // make sure data is set to a default value
        data = (result) ? data : default(T);
        return result;
    }

Bearbeiten: jetzt, wo ich darüber nachdenke, muss ich wirklich den convert.changetype-Test durchführen? versucht die as-Zeile nicht bereits, das zu tun? Ich bin mir nicht sicher, ob dieser zusätzliche Changetype-Aufruf wirklich etwas bringt. Eigentlich könnte es nur den Verarbeitungsaufwand erhöhen, indem es eine Ausnahme erzeugt. Wenn jemand einen Unterschied kennt, der es wert ist, es zu tun, bitte posten!

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