Dela via


CA2208: Instansiera argumentfel korrekt

Property Värde
Regel-ID CA2208
Title Instansiera argumentfel korrekt
Kategori Användning
Korrigeringen är icke-bakåtkompatibel Icke-icke-bryta
Aktiverad som standard i .NET 9 Som förslag

Orsak

När en metod har en parameter och den genererar en undantagstyp som är, eller härleds från, ArgumentExceptionförväntas den anropa en konstruktor som accepterar en paramName parameter korrekt. Möjliga orsaker är följande situationer:

  • Ett anrop görs till standardkonstruktorn (parameterlös) av en undantagstyp som är, eller härleds från, ArgumentException som också har en konstruktor som accepterar en paramName parameter.
  • Ett felaktigt strängargument skickas till en parameteriserad konstruktor av en undantagstyp som är, eller härleds från, ArgumentException. Till exempel matchar argumentet paramName inte namnet på någon av metodens parametrar.
  • Ett parameternamn skickas som argument till konstruktorn för en undantagstyp som är, eller härleds från, ArgumentException.

Regelbeskrivning

I stället för att anropa standardkonstruktorn anropar du en av konstruktorns överlagringar som gör att ett mer meningsfullt undantagsmeddelande kan tillhandahållas. Undantagsmeddelandet bör riktas mot utvecklaren och tydligt förklara feltillståndet och hur du korrigerar eller undviker undantaget.

Signaturerna för en- och två strängkonstruktorerna ArgumentException för och dess härledda typer är inte konsekventa med avseende på position message och paramName parametrar. Kontrollera att dessa konstruktorer anropas med rätt strängargument. Signaturerna är följande:

Så här åtgärdar du överträdelser

Om du vill åtgärda ett brott mot den här regeln anropar du en konstruktor som tar ett meddelande, ett parameternamn eller båda och kontrollerar att argumenten är korrekta för den typ av ArgumentException som anropas.

Dricks

En kodkorrigering är tillgänglig i Visual Studio för felaktigt placerade parameternamn. Om du vill använda den placerar du markören på varningsraden och trycker på Ctrl+. (punkt). Välj Växla argumentordningen från listan över alternativ som visas.

Kodkorrigering för CA2208 – växlingsargument.

Om ett parameternamn i stället för ett meddelande skickas till ArgumentException(String) metoden ger korrigeringsverktyget möjlighet att växla till tvåargumentskonstruktorn i stället.

Kodkorrigering för CA2208 – växla till tvåargumentskonstruktor.

När du ska ignorera varningar

Det är säkert att ignorera en varning från den här regeln endast om en parameteriserad konstruktor anropas med rätt strängargument.

Ignorera en varning

Om du bara vill förhindra en enda överträdelse lägger du till förprocessordirektiv i källfilen för att inaktivera och aktiverar sedan regeln igen.

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

Om du vill inaktivera regeln för en fil, mapp eller ett projekt anger du dess allvarlighetsgrad till none i konfigurationsfilen.

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

Mer information finns i Så här utelämnar du kodanalysvarningar.

Konfigurera kod för analys

Använd följande alternativ för att konfigurera vilka delar av kodbasen som regeln ska köras på.

Du kan konfigurera det här alternativet för bara den här regeln, för alla regler som gäller för eller för alla regler i den här kategorin (design) som den gäller för. Mer information finns i Konfigurationsalternativ för kodkvalitetsregel.

Inkludera specifika API-ytor

Du kan konfigurera vilka delar av kodbasen som ska köra den här regeln baserat på deras tillgänglighet genom att ange alternativet api_surface. Om du till exempel vill ange att regeln endast ska köras mot den icke-offentliga API-ytan lägger du till följande nyckel/värde-par i en .editorconfig-fil i projektet:

dotnet_code_quality.CAXXXX.api_surface = private, internal

Not

Ersätt den XXXX delen av CAXXXX med ID:t för den tillämpliga regeln.

Som standard gäller CA2208-regeln för alla API-ytor (offentliga, interna och privata).

Exempel

Följande kod visar en konstruktor som felaktigt instansierar en instans av 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

Följande kod åtgärdar den tidigare överträdelsen genom att växla konstruktorargumenten.

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

Följande kod visar en metod som felaktigt genererar ArgumentNullException med en paramName som inte matchar någon av metodens parametrar. Regeln utlöses eftersom description är en lokal variabel, inte en metodparameter.

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

Följande kod åtgärdar den tidigare överträdelsen med hjälp InvalidOperationException av i stället, vilket är lämpligt när ett objekts tillstånd är ogiltigt.

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