2009-04-25 6 views
6

Lassen Sie uns sagen, ich habe eine ErweiterungsmethodeC#: Best Practice für "dieses" Argument in Erweiterungsmethoden Validierung

public static T TakeRandom<T>(this IEnumerable<T> e) 
{ 
    ... 

das Argument e Zur Validierung sollte ich:

A) if (e == null) throw new Nullreferenceexception()
B) if (e == null) neues Argument werfen ("e")
C) überprüfe Nicht e

Was ist der Konsens?

Mein erster Gedanke ist immer Argumente zu validieren, so eine ArgumentNullException geworfen. Da TakeRandom() zu einer Methode von e wird, sollte es wiederum eine NullReferenceException sein. Aber wenn es eine NullReferenceException ist, wenn ich versuche, ein Mitglied von e innerhalb von TakeRandom() zu verwenden, wird sowieso NullReferenceException ausgelöst.

Vielleicht sollte ich mit Reflector Peak und herausfinden, was das Framework tut.

+0

Ich hatte genau diese Frage heute in meinem Kopf. Muss StackOverflow.com lieben - Es hat alle Antworten (und Fragen, manchmal mehrmals). :) – orj

Antwort

9

Sie sollten eine ArgumentNullException werfen. Sie versuchen, eine Argumentvalidierung durchzuführen und sollten daher eine Ausnahme auslösen, die auf die Überprüfung von Argumenten abgestimmt ist. NullReferenceException ist keine Argumentüberprüfungsausnahme. Es ist ein Laufzeitfehler.

Nicht vergessen, Erweiterungsmethoden sind nur statische Methoden unter der Haube und können als solche aufgerufen werden. Während es auf der Oberfläche sinnvoll erscheint, eine NullReferenceException für eine Erweiterungsmethode zu verwenden, ist dies für eine statische Methode nicht sinnvoll. Es ist nicht möglich, die Aufrufkonvention in der Methode zu bestimmen, und daher ist ArgumentException die bessere Wahl.

Außerdem sollten Sie niemals explizit eine NullReferenceException auslösen. Dies sollte nur von der CLR ausgelöst werden. Es gibt feine Unterschiede, die beim expliziten Auslösen von Ausnahmen auftreten, die normalerweise nur von der CLR ausgelöst werden.

Das ist, ich bin verrückt, aber da es ein Argument ist, würde ich ein Argument wirft auch in der Nähe einer Betrogene der folgenden

4

Aus Gründen der Konsistenz mit den Enumerable LINQ-Operatoren werfen Sie eine ArgumentNullException (keine NullReferenceException).

Ich würde die Validierung in der TakeRandom-Methode tun, weil der Stack-Trace dann klar machen wird, dass es TakeRandom ist, die gegen ein Null-Argument ist.

1

Vielleicht:/

Allgemein Faustregel ist jedoch, Ausnahmen zu werfen, die von System.ApplicationException abstammen, wenn möglich. NullReferenceException ist etwas, das das Framework/CLR werfen würde.

http://msdn.microsoft.com/en-us/library/system.exception(VS.71).aspx

zwei Kategorien von Ausnahmen existieren unter der Basisklasse Ausnahme:

Die vordefinierten gemeinsame Sprache Laufzeitklassen Ausnahme von Systemexception abgeleitet.Die benutzerdefinierten Anwendungsausnahmeklassen haben von ApplicationException abgeleitet.

+0

"Exceptions auslösen, die von System.ApplicationException abstammen, wenn möglich" - das war Microsofts ursprünglicher Rat für .NET 1.0, aber es hat sich jetzt geändert und ApplicationException ist veraltet. Google für die Gründe. – Joe

+0

@Joe bitte erarbeiten. Auf den extrem seltenen Fall, dass ich meine eigenen Ausnahmen erstellen würde .... Warum sollte ich nicht von ApplicationException erben? Danke –

+0

@Deviant: Ich habe den Artikel nicht handlich, aber ich glaube, dass dies in den Framework Design Guidelines diskutiert wird. Der ursprüngliche Gedanke hinter ApplicationException war, dass Sie "catch (ApplicationException ex)" -Bausteine ​​haben und bei einer Anwendungsausnahme und einer Systemausnahme etwas anderes machen. Dies stellte sich als nicht nützlich heraus und würde erfordern, dass Anwendungscode alle Systemausnahmen in eine Anwendungsausnahme umschließt. Framework Design Guidelines bietet auch gute Regeln für das Erstellen eigener Ausnahmen und das Abfangen von Ausnahmen. –