Schnellere Version von Convert.ChangeType

Schnellere Version von Convert.ChangeType

Mir ist keine andere Funktionalität innerhalb des Frameworks selbst zum Ändern von Typen als Convert.ChangeType bekannt Funktion (und natürlich explizite Umwandlungen).

Ich denke, die einzige andere Möglichkeit, dies zu verbessern, besteht darin, Ihre eigene ChangeType zu würfeln Funktion, die speziell für Ihre spezielle Situation optimiert ist (wenn möglich).

Sie erwähnen, dass Sie mit einer begrenzten Anzahl von Typen arbeiten, vielleicht haben Sie es mit einem Typ mehr zu tun als mit den anderen? Ist so, Ihr ChangeType Die Funktion könnte so optimiert werden, dass sie zuerst diese spezifische Konvertierung versucht und nur andere versucht, wenn sie fehlschlägt. Sie erwähnen das Ausprobieren eines Codeblocks im Switch-Stil, und derselbe Ansatz (das Ausprobieren des am häufigsten verwendeten Typs zuerst) könnte darauf angewendet werden. Ob es schneller sein wird, hängt von Ihren Daten ab, die Sie verarbeiten (und der Häufigkeit/Variabilität der Typen, in die/von denen Sie konvertieren), und die einzige wirkliche Möglichkeit, dies zu messen, besteht darin, es auszuprobieren und zu profilieren Vergleich mit Convert.ChangeType Methodik.

Ein interessanter Link, wenn Sie nach eigenen Funktionen suchen, finden Sie in Peter Johnsons Blog:

Convert.ChangeType verarbeitet keine Nullables

Lesen Sie auch alle Kommentare zum Beitrag.


Dies ist meine Version eines schnelleren ChangeType. Ich denke, das Prinzip ist dasselbe wie von @CraigTP vorgeschlagen, es funktioniert jedoch nur für Nullable-Werttypen.

Ich stütze meine Konvertierungsmethode auf die Tatsache, dass es wahrscheinlicher ist, dass der Werttyp irgendwie mit dem Zieltyp kompatibel ist. Aber diese Methode wurde nicht auf Leistung ausgelegt, sondern auf Bequemlichkeit. Es ist nichts, was ich aus einer engen Schleife heraus aufrufen möchte.

Ich greife immer noch auf ChangeType zurück, aber ich versuche, mich so früh wie möglich abzumelden.

public static T? ToOrDefault<T>(object value)
    where T : struct, IConvertible
{
    var x = value as T?;
    if (x.HasValue)
    {
        return x;
    }
    if (value == null || Convert.IsDBNull(value))
    {
        return null;
    }
    try
    {
        return (T)Convert.ChangeType(value, typeof(T), CultureInfo.InvariantCulture);
    }
    catch (InvalidCastException)
    {
    }
    catch (FormatException)
    {
    }
    catch (OverflowException)
    {
    }
    catch (ArgumentException)
    {
    }
    return default(T?);
}

Ich habe nicht getestet, ob es schneller ist, aber dies ist eine alternative Möglichkeit für dynamisches Casting. Dies ist seit Convert.ChangeType() auch universeller hat einige Einschränkungen, wie Sie gesehen haben (Guids, Nullable-Typen)

value = (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromInvariantString(str);