2011-01-03 7 views
1

Hier sind einige Klassen:Was Ausnahme in String.Concat verursacht

public class MyItem : ParamOut 
{ 
    public string Code 
    { 
     get { return _quoteCode; } 
    } 

    public InnerItem[] Skus 
    { 
     get { return _skus; } 
    } 

    public PriceSummary Price 
    { 
     get { return _price; } 
    } 

    public override string ToString() 
    { 
     return string.Concat("Code=", Code, "; SKUs=[", Skus != null ? "{" + string.Join("},{", Array.ConvertAll(Skus, item => item.ToString())) + "}" : "", "]" 
      , "; Price={", Price.ToString(), "}", base.ToString() 
      ); 
    } 

    ... 
} 

public abstract class ParamOut 
{ 
    public override string ToString() 
    { 
     return null; 
    } 

    public string ErrorMessage { get; set; } 
} 

Hier ruft Funktionalität:

{ 
    MyItem item = new MyItem{ ErrorMessage = "Bla-bla-bla" }; 
    string text = item.ToString(); 
} 

Ich erhalte Nullreference Ausnahme innerhalb von 'ToString()' Methode (jede Eigenschaft der Elementvariable ist null).

Frage:

Q1. Welche Überladung von string.Concat wird in diesem Fall aufgerufen? Ich habe 9-Parameter, also denke ich, eine der folgenden Möglichkeiten:

public static string Concat(params Object[] args) 

oder

public static string Concat(params string[] values) 

Aber welche von ihnen?

Q2. Warum wird eine Ausnahme generiert? Sollte 'null' nicht in etwas wie 'null' oder '' (leere Zeichenkette) umgewandelt werden?

Vielen Dank!

+1

Können Sie die vollständige Traceback und vielleicht einige Beispielausführung, die es wirft werfen? Ich nehme an, dass Sie die Null-Ausnahme auf "item.ToString" innerhalb Ihres ternären Operators oder auf "Price.ToString()" oder "base.ToString()" treffen, und es ist nicht "Concat" selbst, das sich anschnallt eine Null. –

Antwort

2

q1: Sie übergeben nur in Strings, so dass es die Zeichenfolge [] Version

q2 verwenden: zusätzlich zu dem, was matt sagte, auch wenn Concat Nullwerte erlaubt, würden Sie noch bekommen die Ausnahme davon, wo Sie Price.ToString() aufrufen, da Price null ist

0

Soll nicht 'null' in wie etwas umgesetzt werden 'Null' oder "" (leeren string)?

Worauf sollte es konvertiert werden? Einige Leute möchten die leere Zeichenfolge, andere möchten "null", usw. Microsoft hat sich entschieden, das nicht zu beantworten, da es viele Dinge gibt, die hier gültige Antworten wären. MS hat also die sicherere Route genommen und nur eine Ausnahme ausgelöst.

+0

Nur um klar zu sein, ist es der Aufruf von .ToString() auf eine Null-Referenz, die die Ausnahme verursacht, nicht Null auf 'Concat' übergeben. – Greg

+0

Das ist wahr. Aber "Concat" überprüft nicht, ob ein Parameter null ist, und behandelt ihn dann als Spezialfall, so dass meine Antwort in gewisser Weise immer noch gültig ist. MS entschied sich, die Verkettung von Nullen nicht zu behandeln. –

+0

Innerhalb der Methode 'Concat (params string [] values)' werden einzelne Strings * als leer behandelt, wenn sie null sind. http://msdn.microsoft.com/en-us/library/system.string.concat.aspx "Eine leere Zeichenfolge wird anstelle eines beliebigen Nullobjekts im Array verwendet" – Greg

1
  1. Ich denke, dass die Überlastung mit ‚Object []‘ genannt wird (als Parameter verschiedenen Typen verwendet werden) (bitte korrigieren Sie mich, wenn ich falsch).

  2. Price.ToString() verursachte einen Fehler, wenn Price null ist. Und .ToString() ist hier nicht erforderlich bei allen

1
  1. die am besten geeignete Überlastung - wenn alle Parameter Zeichenfolge sind, dann wird der String Überlastung bezeichnet werden. Da dies nicht der Fall ist, wird die Object Überladung aufgerufen.

  2. Die Price könnte die SKU Gegenstände oder sogar Code, null oder einer der folgenden sein, so ToString auf jeder dieser (vorbei an Objekte zu ConcatToString rufen) ruft die Nullreferenceexception werfen.

0

Zunächst einmal, ich vermute, NullReferenceException ist, weil Sie ToString auf ein Nullobjekt aufrufen.

Wenn Sie jedoch versuchen, null zu concat zu geben, erhalten Sie auch diese Ausnahme.

In diesem Fall möchten Sie möglicherweise string.Format verwenden.

return string.Format("Code={0}; SKUs=[{1}]; Price={2}{3}", 
    Code ?? "null", 
    SKUs != null ? 
     string.Join(",", SKUs.Select(s => "{" + s.ToString() ?? "null" + "}")) : 
     string.Empty, 
    (Price ?? "null").ToString() ?? "null", 
    base.ToString() ?? "null"); 

Sie können die Verwendung des Null-Koaleszenz-Operators sehen (??), wo Sie mit einem Nullwert zu tun könnten.

x.ToString() ?? "null" 

ist logisch äquivalent zu

x.ToString() == null ? "null" : x.ToString() 

ich ein bisschen übertrieben, wie viele null Kontrollen sind gegangen, aber es sieht aus wie es eine Menge Potenzial gotchas im Code sind Sie haben da. :)

+0

'x.ToString() ?? "null" 'wird eine" NullReferenceException "auslösen, wenn x null ist. –

+0

Ja, Sie können sehen, dass ich dies für "Preis" gehandhabt habe, aber nicht für die Liste der SKUs. – Sapph

+0

Es wäre auch hilfreich, nur sicherzustellen, dass Ihre eigenen ToString-Methoden niemals 'null' zurückgeben, so dass Sie einfach das Basisobjekt (dh (Preis ??" null "). ToString()) selbst anstelle von jedem überprüfen können ToString-Aufruf ebenfalls. – Sapph

0

Ich glaube, Sie haben es selbst gesagt:

(jede Eigenschaft Elementvariable ist null)

Sie sollten wahrscheinlich prüfen, ob die Anordnung von InnerItem s (von der Skus Eigenschaft) enthält alle null Elemente.

Sie könnten wahrscheinlich mit einer einfachen Where -klausel oder ähnlich vermieden werden.

Und Ihre Fragen zu beantworten:

  • Q1: Die string[] Überlastung aufgerufen wird.
  • Q2: Concat behandelt null als eine leere Zeichenfolge.