CA2208:Argumentausnahmen korrekt instanziieren

CA2208:Argumentausnahmen korrekt instanziieren

Die CA2208-Codeanalyseregel prüft beim Erstellen von Argumentausnahmen auf häufige Fehler. Es gibt drei Hauptargumentausnahmeklassen:ArgumentException, ArgumentNullException und ArgumentOutOfRangeException. Leider ist es leicht, bei der Verwendung einen Fehler zu machen. Ich erkläre die häufigsten Fehler, auf die CA2208 prüft, und wie man sie behebt (und wann man stattdessen die Warnung unterdrückt).

Fall 1 – paramName / Nachricht werden in der falschen Reihenfolge übergeben

Wenn Sie die Argumentausnahmeparameter in der falschen Reihenfolge übergeben, erhalten Sie eine CA2208-Warnung wie:

Hier ist ein Beispiel für dieses Problem. Die Reihenfolge der Parameter ist (paramName, message), und sie werden versehentlich als (message, paramName):

übergeben
//Method signature
public ArgumentOutOfRangeException(string? paramName, string? message);

//Example of passing the parameters in the wrong order:
throw new ArgumentOutOfRangeException("Valid range: 100-999", nameof(id));
Code language: C# (cs)

Hinweis:Um die Sache noch verwirrender zu machen, hat ArgumentException die entgegengesetzte Parameterreihenfolge (message, paramName).

Die einfache Antwort hier ist, die Argumente in die richtige Reihenfolge zu bringen. Ich würde jedoch vorschlagen, stattdessen benannte Argumente zu verwenden.

Wenn Sie zwei Parameter des gleichen Typs (in diesem Fall eine Saite) direkt nebeneinander haben, ist es sehr einfach, sie versehentlich wie oben gezeigt zu transponieren. Der beste Weg, sich gegen diese Art von Problemen im Allgemeinen zu schützen, besteht darin, sich daran zu gewöhnen, benannte Argumente zu verwenden (die die Reihenfolge der Parameter irrelevant machen). Hier ist ein Beispiel für das Erstellen einer Argumentausnahme mit benannten Argumenten:

throw new ArgumentOutOfRangeException(message: "Valid range: 100-999", paramName: nameof(id));
Code language: C# (cs)

Nur den Parameternamen an ArgumentException übergeben

ArgumentException hat keine Überladung, die nur paramName akzeptiert , aber es gibt eine, die nur message akzeptiert . Wenn der Compiler erkennen kann, dass Sie einen Parameternamen für message übergeben , wird dieselbe CA2208-Warnung wie im vorherigen Abschnitt gezeigt gemeldet. Hier ist ein Beispiel dafür, was dies verursachen würde:

throw new ArgumentException(nameof(id));
Code language: C# (cs)

Ist das wirklich ein Problem? Es liegt an dir. Vielleicht möchten Sie wirklich nur den Parameternamen so übergeben und die CA2208-Warnung loswerden. In diesem Fall können Sie CA2208 für diese Codezeile unterdrücken:

#pragma warning disable CA2208 // Instantiate argument exceptions correctly
 throw new ArgumentException(nameof(id));
#pragma warning restore CA2208 // Instantiate argument exceptions correctly
Code language: C# (cs)

Fall 2 – paramName stimmt nicht mit den Parametern der Methode überein

Wenn Sie paramName übergeben Bei einer Argumentausnahme prüft der Compiler, ob es mit dem Namen eines der Methodenparameter übereinstimmt. Ist dies nicht der Fall, erhalten Sie eine CA2208-Warnung wie diese:

Erstens, wenn Sie paramName wollen Um den Namen des Methodenparameters genau abzugleichen, schlage ich vor, den Operator nameof() zu verwenden, anstatt den Namen fest zu codieren:

public Person Get(string uniqueId)
{
	throw new ArgumentNullException(paramName: nameof(uniqueId));
}
Code language: C# (cs)

Nehmen wir zweitens an, Sie verwenden absichtlich den Eigenschaftsnamen eines Parameters anstelle des Namens des Parameters. Hier ist ein Beispiel:

public void Post(Person person)
{
	throw new ArgumentNullException(paramName: nameof(person.FirstName));
}
Code language: C# (cs)

Es ist völlig in Ordnung, eine Argumentausnahme für die Eigenschaft eines Parameters wie diese auszulösen, und zwar paramName stimmt nicht mit dem Parameternamen überein. Wenn Sie in diesem Fall die CA2208-Warnung wirklich loswerden möchten, können Sie sie für diese Zeile unterdrücken:

#pragma warning disable CA2208 // Instantiate argument exceptions correctly
throw new ArgumentNullException(paramName: nameof(person.FirstName));
#pragma warning restore CA2208 // Instantiate argument exceptions correctly
Code language: C# (cs)

Fall 3 – Verwendung eines parameterlosen Konstruktors

Wenn Sie den parameterlosen Konstruktor einer Argumentausnahme verwenden (d. h. new ArgumentException()), erhalten Sie eine CA2208-Warnung wie diese:

Während die Verwendung des parameterlosen Konstruktors technisch nicht falsch ist (er existiert schließlich), ist es in den meisten Fällen wahrscheinlich sinnvoll, message / paramName zu übergeben um spezifische Informationen über die Ausnahme bereitzustellen.

Wenn Sie jedoch entscheiden, dass es sinnvoller ist, den parameterlosen Konstruktor zu verwenden, und Sie die CA2208-Warnung loswerden möchten, können Sie CA2208 für diese Zeile unterdrücken:

#pragma warning disable CA2208 // Instantiate argument exceptions correctly
throw new ArgumentNullException();
#pragma warning restore CA2208 // Instantiate argument exceptions correctly
Code language: C# (cs)