2009-03-09 5 views
6

Angesichts der folgenden Routine:ReSharper Trap "Convert to 'Rückkehr' Anweisung"

private static object ParseNumber(string token, FieldDefinition def) 
{ 
    if (def.Fraction > 0) 
    return Double.Parse(token); 
    else 
    return Int64.Parse(token); 
} 

ReSharper bietet mir die Möglichkeit, es in einer Erklärung mit dem ternären Operator Refactoring:

private static object ParseNumber(string token, FieldDefinition def) 
{ 
    return def.Fraction > 0 ? Double.Parse(token) : Int64.Parse(token); 
} 

kann Wer Finde die Falle?

+0

http://cznp.com/s/7JM –

Antwort

11

Okay, zur vorherigen Antwort wechseln. Da es eine implizite Konvertierung von Int64 zu Double gibt (aber nicht umgekehrt), ist dies der Ergebnistyp des Ausdrucks. Also, wenn Sie erwarten, eine Box Int64 zu erhalten, erhalten Sie tatsächlich eine Box Double (aber mit einem Wert, der ursprünglich von Int64.Parse kam).

Nur für den Fall, dass das nicht klar genug ist, lassen Sie uns alle return Anweisungen so ändern, dass sie nur eine Variable zurückgeben. Hier ist der ursprüngliche Code:

private static object ParseNumber(string token, FieldDefinition def) 
{ 
    if (def.Fraction > 0) 
    return Double.Parse(token); 
    else 
    return Int64.Parse(token); 
} 

konvertieren, die in geeigneter Weise:

private static object ParseNumber(string token, FieldDefinition def) 
{ 
    if (def.Fraction > 0) 
    { 
    double d = Double.Parse(token); 
    object boxed = d; // Result is a boxed Double 
    return boxed; 
    } 
    else 
    { 
    long l = Int64.Parse(token); 
    object boxed = l; // Result is a boxed Int64 
    return boxed; 
    } 
} 

Und nun lassen Sie uns auf die Version mit dem bedingten Operator das gleiche tun:

private static object ParseNumber(string token, FieldDefinition def) 
{ 
    return def.Fraction > 0 ? Double.Parse(token) : Int64.Parse(token); 
} 

wird

private static object ParseNumber(string token, FieldDefinition def) 
{ 
    // The Int64.Parse branch will implicitly convert to Double 
    double d = def.Fraction > 0 ? Double.Parse(token) : Int64.Parse(token); 
    object boxed = d; // *Always* a Double 
    return boxed; 
} 

EDIT: Als reque sted, ein bisschen mehr Informationen. Die Art eines bedingten Ausdruck der Form

X ? Y : Z 

hängt von der Art von Y und Z, die ich TY und TZ nennen würde. Es gibt ein paar Optionen:

  • TY und TZ sind vom gleichen Typ: Ergebnis ist, dass Typ
  • Es gibt eine implizite Konvertierung von TY zu TZ aber nicht von TZ zu TY: Das Ergebnis ist vom Typ TZ und die Die Konvertierung wird verwendet, wenn die erste Verzweigung verwendet wird.
  • Es gibt eine implizite Konvertierung von TZ zu TY aber nicht von TY zu TZ: Das Ergebnis ist vom Typ TY und die Umwandlung verwendet wird, wenn der zweite Zweig verwendet wird.
  • Es gibt eine implizite Konvertierung in beiden Richtungen: Kompilierzeitfehler
  • Es ist keine Umbauten oder so: Fehler bei der Kompilierung

diese Hilfe tun?

+0

Dieser hat mich vorher ... – leppie

+0

Ich postete es etwa 6 Monate zurück auf CodeProject. In der Tat ist es beängstigend, dass eine ganze Zahl implizit doppelt ist, obwohl sie die Genauigkeit verliert. – leppie

+0

Könnten Sie vielleicht einen oder zwei Sätze darüber hinzufügen, warum die implizite Konvertierung zu Double stattfindet?(vermutlich eine Eigenschaft des ternären/bedingten Operators) – Miles