2009-08-31 4 views
50

Ich arbeite an einer Methode, die bei einem String-Parameter etwas tut. Ein gültiger Wert für den Zeichenfolgenparameter ist ein anderer Wert als null oder string.Empty. Also sieht mein Code so aus.Soll ich ArgumentNullException werfen, wenn eine Zeichenfolge leer ist?

 
private void SomeMethod(string someArgument) 
{ 
    if(string.IsNullOrEmpty(someArgument)) 
     throw new ArgumentNullException("someArgument"); 

    // do some work 
} 

Nichts zu aufregend dort. Meine Frage ist, ist es in Ordnung, eine ArgumentNullException zu werfen, auch wenn die Zeichenfolge gleich string.Empty ist? Weil es technisch nicht null ist. Wenn Sie der Meinung sind, dass ArgumentNullException nicht ausgelöst werden soll, welche Ausnahme sollte ausgelöst werden?

+1

Werfen ArgumentNullException, wenn Zeichenfolge "" ist irreführend. –

+0

Ich stimme zu, leider der Grund, warum ich es vorher so gemacht habe, ist wegen der Antwort "Joe" gegeben, es wird so im .net Framework-Code verwendet. – Kepboy

Antwort

35

ArgumentException sollte für den String.Empty Fall geworfen werden. Dies würde auf ein anderes Problem hinweisen, als dass es null ist. Um eine NullReferenceException zu vermeiden, überprüfe ich zunächst auf Null, dann trimme ich und überprüfe den leeren Fall, um zu verhindern, dass irgendwelche Leerzeichen passieren.

private void SomeMethod(string someArgument) 
{ 
    if(someArgument == null) 
     throw new ArgumentNullException("someArgument"); 

    if (someArgument.Trim() == String.Empty) 
     throw new ArgumentException("Input cannot be empty", "someArgument"); 

    // do some work 
} 

Ab .NET 4.0 können Sie die String.IsNullOrWhiteSpace Methode verwenden, um diese Kontrollen in einem Rutsch durchzuführen. Auf diese Weise verzichten Sie auf die Möglichkeit, einen granularen Ausnahmetyp anzugeben. Daher würde ich mich für die ArgumentException entscheiden und die Nachricht entsprechend aktualisieren.

+0

Ich verwende C# 2.0, der einzige Verweis auf InvalidArgumentException ist im Microsoft.SqlServer.Management.Common-Namespace, was empfehlen Sie oder schlagen Sie vor, dass ich meine eigene InvalidArgumentException-Klasse erstelle? – Kepboy

+0

@Keith: Du hast Recht, mein Fehler. Sie könnten Ihre eigenen schreiben, wenn Sie dazu geneigt sind, oder Sie verwenden die ArgumentException, die vom Framework bereitgestellt wird. Ich werde bearbeiten, um den richtigen Namen zu reflektieren. –

+3

Der ArgumentException-Konstruktor benötigt keinen paramName-Parameter wie ArgumentNullException. So 'throw new ArgumentException ("paramName") ist möglicherweise verwirrend, da es keinen Hinweis darauf gibt, was mit dem Argument falsch ist. Sie sollten ein "message" -Argument bereitstellen, etwa so ("someArgument darf keine leere Zeichenfolge sein"). Und in einer internationalen App müsste diese Nachricht lokalisiert werden. Daher würde ich nur zu all diesen Schwierigkeiten gehen, wenn es wirklich notwendig wäre, den Nullfall von dem Leerstreichfall zu unterscheiden. – Joe

5

Sie sollten eine ArgumentException werfen, wenn eine leere Zeichenfolge keine akzeptierte Eingabe für Ihre Methode ist. Es kann für Kunden sehr verwirrend sein, wenn Sie eine ArgumentNullException werfen, während sie kein null Argument zur Verfügung stellten.

Es ist einfach ein anderer Anwendungsfall. Möglicherweise verfügen Sie auch über Methoden, die keine Nulleingabewerte akzeptieren, aber leere Zeichenfolgen akzeptieren. Es ist wichtig, dass Sie in Ihrer gesamten Anwendung konsistent sind.

+0

Ich dachte nach ArgumentOutOfRangeException, aber vielleicht wird das für Array-Indexbereich Ausnahmen verwendet. – Kepboy

+0

Für Array-Index-Ausnahmen wird IndexOutOfRangeException verwendet. Sie sollten ArgumentOutOfRangeException nur verwenden, wenn Ihre Methode dokumentiert ist, nur eine bestimmte Sammlung von Zeichenfolgen (z.: "abc", "def", "ghi" sind die einzigen akzeptierten Eingaben. –

+0

Danke für die Klärung. – Kepboy

1

In .NET Framework wird manchmal die ArgumentNullException für den String.IsNullOrEmpty-Fall verwendet - ein Beispiel ist System.Windows.Forms.Clipboard.SetText.

Also ich denke, es ist sinnvoll, das gleiche in Ihrem Code zu tun, es sei denn, es gibt einen echten Wert bei der Unterscheidung der beiden Fälle.

Beachten Sie, dass diese und andere von ArgumentException abgeleitete Ausnahmen im Allgemeinen einen Programmierfehler anzeigen und daher Informationen bereitstellen müssen, die einem Entwickler bei der Diagnose des Problems helfen. Ich persönlich denke, es ist unwahrscheinlich, dass ein Entwickler es verwirrend finden würde, wenn Sie ArgumentNullException für ein leeres String-Argument verwenden, besonders wenn Sie dieses Verhalten wie im folgenden Beispiel dokumentieren.

/// <summary> 
/// ... description of method ... 
/// </summary> 
/// <param name="someArgument">... description ...</param> 
/// <exception cref="ArgumentNullException">someArgument is a null reference or Empty.</exception> 
public void SomeMethod(string someArgument) 
{ 
    ... 
} 
+4

Ich würde nicht nach Windows Forms für Beispiele der neuesten Best Practices in .NET Framework-Code suchen. Ich konnte schnell ein Gegenbeispiel in File.Copy (string, string) finden, das ArgumentNullException für null und ArgumentException für leer wirft. – dcstraw

4

Wenn man all die Dinge zu berücksichtigen, dass (Joe/Ahmad Mageed) hat gesagt, würde ich dann eine Ausnahme für diesen Fall erstellen.

class ArgumentNullOrEmptyException : ArgumentNullException 
+14

Wäre es nicht besser, von ArgumentException abzuleiten? In OOP scheint es nicht richtig zu sagen, dass "A oder B" ein "A" ist. – dcstraw

+0

@dcstraw ArgumentNullException wird von ArgumentException abgeleitet. In diesem Fall denke ich, dass es besser ist, ArgumentNullOrEmptyException von ArgumentNullException abzuleiten. – Xtro

+0

Auch ich denke, sein Name sollte StringArgumentNullOrEmptyException sein, weil es nur eine Bedeutung für String-Argumente hat. – Xtro

0

Dies hängt von den Umständen wirklich ab.

Die Frage kommt auf, ist es wirklich ein Fehler? Damit meine ich, Sie immer einen Wert erwarten? Wenn Sie das tun, dann wahrscheinlich die hier beste Wette Ihre eigenen Exception schafft, vielleicht etwa so:

class StringEmptyOrNullException : Exception 
{ 
} 

Wo Sie können auch Ihre eigenen Konstrukteuren hinzufügen und hinzugefügt Informationen etc.

Wenn es jedoch nicht ist "Ausnahme" passiert in Ihrem Programm, wenn es wahrscheinlich eine bessere Idee wäre, null von der Methode zurückzugeben und von dort aus zu behandeln.Denken Sie daran, Exception sind für außergewöhnliche Bedingungen.

hoffe, das hilft,

Kyle

+1

Wenn Sie * eine * eigene Exception erstellen, sollte sie von ArgumentException und nicht von Exception abgeleitet sein. – Joe

+0

Je nach Kontext wirklich, in diesem Zusammenhang ja. Wenn Sie es an anderen Orten verwenden möchten, machen Sie es generischer. Wenn Sie beispielsweise eine Methode haben, die eine Zeichenfolge generiert, die nicht leer sein sollte, ist ArgumentException nicht die beste Wahl. Also, abhängig von der Menge der Verwendung, die Sie dafür haben, und dem Kontext, in dem es verwendet wird, werden Sie dann entscheiden, was Sie erben. –

+0

IMO das sind zwei verschiedene Situationen - Methode generiert einen String und ein Argument in eine Methode übergeben, und ich würde lieber zwei verschiedene Arten von Ausnahmen haben. Es ist besser, ausführlich zu sein, als mehrere Arten von Fehlersituationen in einer einzigen Ausnahme zu stauen. –

0

Warum diesen Code nicht verwenden?

private void SomeMethod(string someArgument) 
{ 
//chek only NULL 
if(ReferenceEquals(someArgument,null)) 
    throw new ArgumentNullException("someArgument"); 

// and after trim and check 
if (someArgument.Trim() == String.Empty) 
    throw new ArgumentException("Input cannot be empty", "someArgument"); 

// do some work 
} 
Verwandte Themen