2009-10-07 12 views
10

In einer Anwendung, die ich habe, mache ich recht häufig Anrufe Convert.ChangeType, um einen Wert zu einem dynamisch geladenen Typ zu konvertieren.Schnellere Version von Convert.ChangeType

Allerdings, nach dem Profiling mit ANTS, habe ich festgestellt, dass diese Convert.ChangeType scheint einen erheblichen Teil der Zeit zu nehmen (aufgrund der oft aufgerufen wird). Hat jemand eine schnellere Alternative dazu?

An diesem Punkt habe ich einen Typ Objekt das Ziel, und ein string enthält den Wert enthält.

Im Folgenden ist der säumige Code. Ich habe erwogen, eine switch-Anweisung für type (da es sich um eine begrenzte Sammlung von Typen handelt) und die Parse-Methoden aufzurufen, obwohl ich mir nicht sicher bin, ob das schneller sein wird oder nicht.

if(attributeRow["Value"]!=DBNull.Value) 
    sample[attr] = attr.AttributeType == typeof(Guid) 
       ? new Guid(attributeRow["Value"].ToString()) 
       : (IComparable)Convert.ChangeType(attributeRow["Value"],attr.AttributeType); 

Antwort

9

Ich kenne keine andere Funktionalität innerhalb des Frameworks selbst für andere Typen als die Convert.ChangeType-Funktion (und natürlich explizite Umwandlungen).

Dafür, ich denke, der einzige andere Weg, dies zu verbessern, ist Ihre eigene ChangeType Funktion rollen, 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 bist du mit einer Art mehr als die anderen zu tun? Ist dies der Fall, könnte Ihre ChangeType-Funktion optimiert werden, um zuerst diese spezifische Umwandlung zu versuchen und nur andere zu versuchen, wenn sie fehlschlagen. Sie erwähnen den Versuch, einen Code-Code im Switch-Stil zu verwenden, und dieser Ansatz (mit dem am häufigsten verwendeten Typ zuerst) könnte darauf angewendet werden. Ob es schneller geht, hängt von Ihren Daten ab, die Sie verarbeiten (und von der Häufigkeit/Variabilität der Typen, in die Sie konvertieren). Die einzige Möglichkeit, dies zu messen, besteht darin, es auszuprobieren und zu profilieren Vergleich mit der Convert.ChangeType Methodik.

Ein interessanter Link, wenn Sie schauen, um Roll-your-own-Funktionalität ist auf Peter Johnson Blog:

Convert.ChangeType doesn't handle nullables

Seien Sie sicher, dass auch alle Kommentare zum Post lesen.

+0

Wir werden uns ein paar Dinge ansehen, aber dieser Beitrag bestätigt meine Befürchtung, dass wir es so gut wie möglich tun würden, also akzeptiere ich diese Antwort. – Erich

+0

Der ChangeType im Link funktioniert einwandfrei! Vielen Dank! – Larry

0

Sie könnten Ihre eigene ChangeType Funktion rollen, die gerade tut statisches Gießen C-Stil. Das wäre mein Ansatz.

+0

Das Problem ist, dass die Quelle ein String ist, nicht ein tatsächlicher Wert, so Casting würde ich nicht arbeiten würde verdächtigen. – Erich

3

Dies ist meine Version eines schnelleren ChangeType. Ich denke, das Prinzip ist das gleiche wie von @CraigTP vorgeschlagen, aber es funktioniert nur für Nullwerttypen.

ich meine convert-Methode auf der Tatsache gestützt, dass es wahrscheinlicher ist, dass die Art des Wertes mit dem Zieltyp kompatibel sein wird, ist eine Möglichkeit. Aber diese Methode wurde nicht für die Leistung entwickelt, es wurde entworfen, um bequem zu sein. Es ist nichts, was ich aus einer engen Schleife herausrufen möchte.

Ich falle immer noch auf Change zurück, aber ich versuche, so früh wie möglich zu deaktivieren.

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?); 
} 
+0

Können Sie bitte zeigen, wie Sie den obigen Code in Ihrem Code verwenden? – Naomi

+0

Nun, betrachten Sie die 'DataTable' Klasse, wenn Sie irgendwo einen Wert haben, werden sie alle als' Objekt' exponiert, nehmen wir an, Sie wissen, dass irgendwo eine Zahl ist, dann erhalten Sie diesen Wert wie folgt: ' DataTable-Tabelle; int? num = ToOrDefault (table.Rows [0] [3]); 'Das wird gelingen, wenn es möglich ist, an die Zahl zu kommen, aber ansonsten Null zurückgibt. Keine Ausnahmen werfen! –

+0

Die Catch'em'all Teil Ihres Codes inspiriert mich Angst und Terror. Wenn etwas nicht stimmt (Ausnahme), kann das Ignorieren des Fehlers zu Datenintegritätsproblemen führen. – SandRock

0

Ich habe nicht getestet, wenn schneller, aber dies ist eine alternative Möglichkeit für dynamisches Gießen.Dies ist alsp universellere, da Convert.ChangeType() hat einige Einschränkungen, wie Sie (Guids, Nullable-Typen) gesehen haben

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