Bagikan melalui


CA2208: Buat instans pengecualian argumen dengan benar

Properti Nilai
ID Aturan CA2208
Judul Buat instans pengecualian argumen dengan benar
Golongan Penggunaan
Perbaikan bersifat disruptif atau non-disruptif Non-disruptif
Diaktifkan secara default di .NET 10 Sebagai saran

Penyebab

Ketika metode memiliki parameter, dan menampilkan jenis pengecualian yaitu, atau berasal dari, ArgumentException, diharapkan untuk memanggil konstruktor yang menerima parameter paramName dengan benar. Kemungkinan penyebabnya mencakup situasi berikut:

  • Panggilan dilakukan ke konstruktor default (tanpa parameter) dari jenis pengecualian yang, atau berasal dari, ArgumentException yang juga memiliki konstruktor yang menerima paramName parameter.
  • Argumen string yang salah diteruskan ke konstruktor berparameter dari jenis pengecualian yaitu, atau berasal dari, ArgumentException. Misalnya, paramName argumen tidak cocok dengan nama salah satu parameter metode.
  • Nama parameter yang diteruskan sebagai argumen message untuk konstruktor dari jenis pengecualian yang merupakan, atau berasal dari, ArgumentException.

Deskripsi aturan

Alih-alih memanggil konstruktor default, panggil salah satu konstruktor kelebihan beban yang mengizinkan penyediaan pesan pengecualian yang lebih bermakna. Pesan pengecualian harus menargetkan pengembang dan menjelaskan dengan jelas kondisi kesalahan dan cara memperbaiki atau menghindari pengecualian.

Tanda tangan dari satu dan dua konstruktor string ArgumentException dan jenis turunannya tidak konsisten sehubungan dengan posisi parameter message dan paramName. Pastikan konstruktor ini dipanggil dengan argumen string yang benar. Tanda tangannya adalah sebagai berikut:

Cara memperbaiki pelanggaran

Untuk memperbaiki pelanggaran aturan ini, panggil konstruktor yang mengambil pesan, nama parameter, atau keduanya, dan pastikan argumen tepat untuk jenis ArgumentException yang dipanggil.

Tip

Perbaikan kode tersedia di Visual Studio untuk nama parameter yang salah diposisikan. Untuk menggunakannya, posisikan kursor pada baris pelanggaran dan tekan Ctrl+. (titik). Pilih Tukar urutan argumen dari daftar opsi yang disajikan.

Perbaikan kode untuk CA2208 - argumen pertukaran.

Jika nama parameter alih-alih pesan diteruskan ke metode ArgumentException(String), fixer menyediakan opsi untuk beralih ke konstruktor dua argumen sebagai gantinya.

Perbaikan kode untuk CA2208 - beralih ke konstruktor dua argumen.

Kapan harus menekan peringatan

Aman untuk menyembunyikan peringatan dari aturan ini hanya jika konstruktor berparameter dipanggil dengan argumen string yang benar.

Menyembunyikan peringatan

Jika Anda hanya ingin menyembunyikan satu pelanggaran, tambahkan arahan praprosedur ke file sumber Anda untuk dinonaktifkan lalu aktifkan kembali aturannya.

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

Untuk menonaktifkan aturan untuk file, folder, atau proyek, atur tingkat keparahannya ke none dalam file konfigurasi.

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

Untuk informasi selengkapnya, lihat Cara menyembunyikan peringatan analisis kode.

Mengonfigurasi kode yang akan dianalisis

Gunakan opsi berikut untuk mengonfigurasi bagian mana dari codebase Anda yang akan menjalankan aturan ini.

Anda dapat mengonfigurasi opsi ini hanya untuk aturan ini, untuk semua aturan yang berlaku untuknya, atau untuk semua aturan dalam kategori ini (Desain) yang berlaku untuk aturan ini. Untuk informasi selengkapnya, lihat Opsi konfigurasi aturan kualitas kode.

Menyertakan permukaan API tertentu

Anda dapat mengonfigurasi bagian basis kode mana yang akan dijalankan aturan ini, berdasarkan aksesibilitasnya, dengan mengatur opsi api_surface. Misalnya, untuk menentukan bahwa aturan hanya boleh dijalankan pada permukaan API non-publik, tambahkan pasangan kunci-nilai berikut ke file .editorconfig di proyek Anda:

dotnet_code_quality.CAXXXX.api_surface = private, internal

Nota

Ganti bagian XXXXCAXXXX dengan ID aturan yang berlaku.

Secara default, aturan CA2208 berlaku untuk semua permukaan API (publik, internal, dan privat).

Contoh

Kode berikut menunjukkan konstruktor yang salah membuat instans 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

Kode berikut memperbaiki pelanggaran sebelumnya dengan mengalihkan argumen konstruktor.

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

Kode berikut menunjukkan metode yang salah melempar ArgumentNullException dengan menggunakan paramName, yang tidak sesuai dengan parameter apa pun dari metode tersebut. Aturan diaktifkan karena description merupakan variabel lokal, bukan parameter metode.

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

Kode berikut memperbaiki pelanggaran sebelumnya dengan menggunakan InvalidOperationException sebagai gantinya, yang sesuai ketika status objek tidak valid.

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