Bagikan melalui


Menentukan informasi pemanggil dengan menggunakan atribut yang ditafsirkan pengkompilasi C#

Dengan menggunakan atribut info, Anda bisa mendapatkan informasi tentang pemanggil ke metode . Anda bisa mendapatkan jalur file kode sumber, nomor baris dalam kode sumber, dan nama anggota pemanggil. Untuk mendapatkan informasi pemanggil anggota, gunakan atribut yang Anda terapkan ke parameter opsional. Setiap parameter opsional menentukan nilai default.

Referensi bahasa C# mendanai versi bahasa C# yang terbaru dirilis. Ini juga berisi dokumentasi awal untuk fitur dalam pratinjau publik untuk rilis bahasa yang akan datang.

Dokumentasi mengidentifikasi fitur apa pun yang pertama kali diperkenalkan dalam tiga versi terakhir bahasa atau dalam pratinjau publik saat ini.

Tip

Untuk menemukan kapan fitur pertama kali diperkenalkan di C#, lihat artikel tentang riwayat versi bahasa C#.

Tabel berikut mencantumkan atribut Info Penelepon yang ditentukan di System.Runtime.CompilerServices namespace:

Karakteristik Deskripsi Tipe
CallerFilePathAttribute Jalur lengkap file sumber yang berisi pemanggil. Jalur lengkap adalah jalur pada waktu kompilasi. String
CallerLineNumberAttribute Nomor baris dalam file sumber tempat metode dipanggil. Integer
CallerMemberNameAttribute Nama metode atau nama properti pemanggil. String
CallerArgumentExpressionAttribute Representasi string dari ekspresi argumen. String

Informasi ini membantu Anda melacak dan menelusuri kesalahan, dan membantu Anda membuat alat diagnostik. Contoh berikut menunjukkan cara menggunakan atribut info penelepon. Pada setiap panggilan ke TraceMessage metode , informasi pemanggil dimasukkan untuk argumen ke parameter opsional.

public void DoProcessing()
{
    TraceMessage("Something happened.");
}

public void TraceMessage(string message,
        [CallerMemberName] string memberName = "",
        [CallerFilePath] string sourceFilePath = "",
        [CallerLineNumber] int sourceLineNumber = 0)
{
    Trace.WriteLine("message: " + message);
    Trace.WriteLine("member name: " + memberName);
    Trace.WriteLine("source file path: " + sourceFilePath);
    Trace.WriteLine("source line number: " + sourceLineNumber);
}

// Sample Output:
//  message: Something happened.
//  member name: DoProcessing
//  source file path: c:\Visual Studio Projects\CallerInfoCS\CallerInfoCS\Form1.cs
//  source line number: 31

Anda menentukan nilai default eksplisit untuk setiap parameter opsional. Anda tidak dapat menerapkan atribut info penelepon ke parameter yang tidak opsional. Atribut info penelepon tidak membuat parameter opsional. Sebaliknya, mereka memengaruhi nilai default yang diteruskan saat argumen dihilangkan. Pengkompilasi memancarkan nilai info pemanggil sebagai harfiah ke dalam Bahasa Perantara (IL) pada waktu kompilasi. Tidak seperti hasil StackTrace properti untuk pengecualian, obfuscation tidak memengaruhi hasilnya. Anda dapat secara eksplisit menyediakan argumen opsional untuk mengontrol informasi penelepon atau menyembunyikan informasi penelepon.

Nama anggota

CallerMemberName Gunakan atribut untuk menghindari menentukan nama anggota sebagai String argumen ke metode yang disebut. Dengan menggunakan teknik ini, Anda menghindari masalah bahwa Pemfaktoran Ulang Nama tidak mengubah String nilai. Manfaat ini sangat berguna untuk tugas-tugas berikut:

  • Menggunakan prosedur pelacakan dan diagnostik.
  • Menerapkan INotifyPropertyChanged antarmuka saat mengikat data. Antarmuka ini memungkinkan properti objek untuk memberi tahu kontrol terikat bahwa properti berubah. Kontrol dapat menampilkan informasi yang diperbarui. CallerMemberName Tanpa atribut , Anda harus menentukan nama properti sebagai harfiah.

Bagan berikut menunjukkan nama anggota yang dikembalikan saat Anda menggunakan CallerMemberName atribut .

Panggilan terjadi di dalam Hasil nama anggota
Metode, properti, atau peristiwa Nama metode, properti, atau peristiwa tempat panggilan berasal.
Pembangun String ".ctor"
Konstruktor statis String ".cctor"
Finalizer String "Finalisasi"
Operator atau konversi yang ditentukan pengguna Nama yang dihasilkan untuk anggota, misalnya, "op_Addition".
Konstruktor atribut Nama metode atau properti tempat atribut diterapkan. Jika atribut adalah elemen apa pun dalam anggota (seperti parameter, nilai pengembalian, atau parameter jenis generik), hasil ini adalah nama anggota yang terkait dengan elemen tersebut.
Tidak berisi anggota (misalnya, tingkat majelis atau atribut yang diterapkan pada tipe) Nilai default dari parameter opsional.

Ekspresi argumen

System.Runtime.CompilerServices.CallerArgumentExpressionAttribute Gunakan saat Anda ingin ekspresi diteruskan sebagai argumen. Pustaka diagnostik dapat memberikan detail selengkapnya tentang ekspresi yang diteruskan ke argumen. Dengan memberikan ekspresi yang memicu diagnostik, selain nama parameter, pengembang memiliki detail lebih lanjut tentang kondisi yang memicu diagnostik. Informasi tambahan itu membuatnya lebih mudah diperbaiki.

Contoh berikut menunjukkan bagaimana Anda dapat memberikan informasi terperinci tentang argumen saat tidak valid:

public static void ValidateArgument(string parameterName, bool condition, [CallerArgumentExpression("condition")] string? message=null)
{
    if (!condition)
    {
        throw new ArgumentException($"Argument failed validation: <{message}>", parameterName);
    }
}

Anda memanggilnya seperti yang ditunjukkan dalam contoh berikut:

public void Operation(Action func)
{
    Utilities.ValidateArgument(nameof(func), func is not null);
    func();
}

Pengkompilasi menyuntikkan ekspresi yang digunakan untuk condition ke dalam message argumen. Saat pengembang memanggil Operation dengan null argumen, pesan berikut disimpan di ArgumentException:

Argument failed validation: <func is not null>

Dengan menggunakan atribut ini, Anda dapat menulis utilitas diagnostik yang memberikan detail lebih lanjut. Pengembang dapat lebih cepat memahami perubahan apa yang diperlukan. Anda juga dapat menggunakan CallerArgumentExpressionAttribute untuk menentukan ekspresi apa yang digunakan sebagai penerima untuk anggota ekstensi. Metode berikut mengambil sampel urutan secara berkala. Jika urutannya memiliki lebih sedikit elemen daripada frekuensi, urutan melaporkan kesalahan:

extension<T>(IEnumerable<T> sequence)
{
    public IEnumerable<T> Sample(int frequency, 
        [CallerArgumentExpression(nameof(sequence))] string? message = null)
    {
        if (sequence.Count() < frequency)
            throw new InvalidOperationException($"Expression doesn't have enough elements: {message}");
        int i = 0;
        foreach (T item in sequence)
        {
            if (i++ % frequency == 0)
                yield return item;
        }
    }
}

Contoh sebelumnya menggunakan nameof operator untuk parameter sequence. Anda dapat memanggil metode ini sebagai berikut:

sample = Enumerable.Range(0, 10).Sample(100);

Contoh sebelumnya melemparkan ArgumentException pesan yang merupakan teks berikut:

Expression doesn't have enough elements: Enumerable.Range(0, 10) (Parameter 'sequence')

Lihat juga