Delen via


CA2208: Argument-uitzonderingen op de juiste manier instantiëren

Eigenschappen Weergegeven als
Regel-id CA2208
Titel Argument-uitzonderingen op de juiste manier instantiëren
Categorie Gebruik
Oplossing is brekend of niet-brekend Niet-brekend
Standaard ingeschakeld in .NET 9 Als suggestie

Oorzaak

Wanneer een methode een parameter heeft en er een uitzonderingstype wordt gegenereerd dat is, of is afgeleid van, wordt verwacht dat een constructor die een ArgumentException parameter juist accepteert, paramNameaanroept. Mogelijke oorzaken zijn de volgende situaties:

  • Er wordt een aanroep uitgevoerd naar de standaardconstructor (parameterloos) van een uitzonderingstype dat is of is afgeleid van, ArgumentException die ook een constructor heeft die een paramName parameter accepteert.
  • Er wordt een onjuist tekenreeksargument doorgegeven aan een geparameteriseerde constructor van een uitzonderingstype dat wel of niet is afgeleid van. ArgumentException Het argument komt bijvoorbeeld paramName niet overeen met de naam van een van de parameters van de methode.
  • Er wordt een parameternaam doorgegeven voor het message-argument van de constructor van een uitzonderingstype dat, ofwel zelf, of afgeleid is van ArgumentException.

Beschrijving van regel

In plaats van de standaardconstructor aan te roepen, roept u een van de constructoroverbelastingen aan waarmee een duidelijker uitzonderingsbericht kan worden opgegeven. Het uitzonderingsbericht moet gericht zijn op de ontwikkelaar en duidelijk de foutvoorwaarde uitleggen en hoe de uitzondering moet worden gecorrigeerd of vermeden.

De handtekeningen van de ene en twee tekenreeksconstructors van ArgumentException en de afgeleide typen zijn niet consistent met betrekking tot de positie message en paramName parameters. Zorg ervoor dat deze constructors worden aangeroepen met de juiste tekenreeksargumenten. De handtekeningen zijn als volgt:

Schendingen oplossen

Als u een schending van deze regel wilt oplossen, roept u een constructor aan die een bericht, een parameternaam of beide gebruikt en controleert u of de argumenten juist zijn voor het type ArgumentException aangeroepen.

Tip

Er is een codeoplossing beschikbaar in Visual Studio voor onjuist geplaatste parameternamen. Als u deze wilt gebruiken, plaatst u de cursor op de waarschuwingsrij en drukt u op Ctrl+. (punt). Kies De volgorde van argumenten wisselen in de lijst met opties die worden weergegeven.

Codefix voor CA2208 - argumenten wisselen.

Als een parameternaam in plaats van een bericht wordt doorgegeven aan de ArgumentException(String) methode, biedt de fixer de optie om over te schakelen naar de constructor met twee argumenten.

Codefix voor CA2208: overschakelen naar constructor met twee argumenten.

Wanneer waarschuwingen onderdrukken

Het is veilig om een waarschuwing van deze regel alleen te onderdrukken als een geparameteriseerde constructor wordt aangeroepen met de juiste tekenreeksargumenten.

Een waarschuwing onderdrukken

Als u slechts één schending wilt onderdrukken, voegt u preprocessorrichtlijnen toe aan uw bronbestand om de regel uit te schakelen en vervolgens opnieuw in te schakelen.

#pragma warning disable CA2208
// The code that's violating the rule is on this line.
#pragma warning restore CA2208

Als u de regel voor een bestand, map of project wilt uitschakelen, stelt u de ernst none ervan in op het configuratiebestand.

[*.{cs,vb}]
dotnet_diagnostic.CA2208.severity = none

Zie Codeanalysewaarschuwingen onderdrukken voor meer informatie.

Code configureren om te analyseren

Gebruik de volgende optie om te configureren op welke onderdelen van uw codebase deze regel moet worden uitgevoerd.

U kunt deze optie configureren voor alleen deze regel, voor alle regels waarop deze van toepassing is, of voor alle regels in deze categorie (ontwerp) waarop deze van toepassing is. Zie de configuratieopties voor de codekwaliteitsregel voor meer informatie.

Specifieke API-oppervlakken opnemen

U kunt configureren op welke onderdelen van uw codebase deze regel moet worden uitgevoerd, op basis van hun toegankelijkheid, door de optie api_surface in te stellen. Als u bijvoorbeeld wilt opgeven dat de regel alleen moet worden uitgevoerd op het niet-openbare API-oppervlak, voegt u het volgende sleutel-waardepaar toe aan een .editorconfig-bestand in uw project:

dotnet_code_quality.CAXXXX.api_surface = private, internal

Notitie

Vervang het XXXX deel van CAXXXX door de id van de toepasselijke regel.

De CA2208-regel is standaard van toepassing op alle API-oppervlakken (openbaar, intern en privé).

Opmerking

De volgende code toont een constructor die een instantie van ArgumentNullException.

public class Book
{
    public Book(string title)
    {
        Title = title ??
            throw new ArgumentNullException("All books must have a title.", nameof(title));
    }

    public string Title { get; }
}
Public Class Book

    Private ReadOnly _Title As String

    Public Sub New(ByVal title As String)
        ' Violates this rule (constructor arguments are switched)            
        If (title Is Nothing) Then
            Throw New ArgumentNullException("title cannot be a null reference (Nothing in Visual Basic)", "title")
        End If
        _Title = title
    End Sub

    Public ReadOnly Property Title()
        Get
            Return _Title
        End Get
    End Property

End Class

Met de volgende code wordt de vorige schending opgelost door de constructorargumenten over te schakelen.

public class Book
{
    public Book(string title)
    {
        Title = title ??
            throw new ArgumentNullException(nameof(title), "All books must have a title.");
    }

    public string Title { get; }
}
Public Class Book

    Private ReadOnly _Title As String

    Public Sub New(ByVal title As String)
        If (title Is Nothing) Then
            Throw New ArgumentNullException("title", "title cannot be a null reference (Nothing in Visual Basic)")
        End If

        _Title = title
    End Sub

    Public ReadOnly Property Title()
        Get
            Return _Title
        End Get
    End Property

End Class

In de volgende code ziet u een methode die onjuist een ArgumentNullException gooit met een paramName die niet overeenkomt met een van de parameters van de methode. De regel wordt geactiveerd omdat description dit een lokale variabele is, niet een methodeparameter.

public class Product
{
    public string? Description { get; set; }
    public string Name { get; set; } = string.Empty;
}

public class Example
{
    // Violates CA2208: 'description' is not a parameter of this method.
    public void ProcessProduct(Product product)
    {
        string? description = product.Description;
        if (description is null)
        {
            throw new ArgumentNullException(nameof(description), $"Product named {product.Name} had no description!");
        }
        // Process description...
    }
}
Public Class Product
    Public Property Description As String
    Public Property Name As String = String.Empty
End Class

Public Class Example
    ' Violates CA2208: 'description' is not a parameter of this method.
    Public Sub ProcessProduct(ByVal product As Product)
        Dim description As String = product.Description
        If description Is Nothing Then
            Throw New ArgumentNullException(NameOf(description), $"Product named {product.Name} had no description!")
        End If
        ' Process description...
    End Sub
End Class

Met de volgende code wordt de vorige schending opgelost met behulp van InvalidOperationException in plaats daarvan, wat geschikt is wanneer de status van een object ongeldig is.

public class Product
{
    public string? Description { get; set; }
    public string Name { get; set; } = string.Empty;
}

public class Example
{
    // Fixed: Use InvalidOperationException for invalid object state.
    public void ProcessProduct(Product product)
    {
        string? description = product.Description;
        if (description is null)
        {
            throw new InvalidOperationException($"Product named {product.Name} had no description!");
        }
        // Process description...
    }
}
Public Class Product
    Public Property Description As String
    Public Property Name As String = String.Empty
End Class

Public Class Example
    ' Fixed: Use InvalidOperationException for invalid object state.
    Public Sub ProcessProduct(ByVal product As Product)
        Dim description As String = product.Description
        If description Is Nothing Then
            Throw New InvalidOperationException($"Product named {product.Name} had no description!")
        End If
        ' Process description...
    End Sub
End Class