Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Variabel placeholder adalah variabel yang sengaja tidak digunakan dalam kode aplikasi. Pembuangan setara dengan variabel yang tidak ditetapkan; mereka tidak mempunyai nilai. Buangan menunjukkan kepada kompiler dan orang lain yang membaca kode Anda bahwa Anda bermaksud mengabaikan hasil dari suatu ekspresi. Anda mungkin ingin mengabaikan hasil ekspresi, satu atau beberapa anggota ekspresi tuple, parameter dalam metode, atau target pada ekspresi pencocokan pola.
Pengabaian membuat intent kode pemrograman Anda menjadi jelas. Pembuangan menunjukkan bahwa kode kami tidak pernah menggunakan variabel. Mereka meningkatkan keterbacaan dan kemudahan pemeliharaan.
Anda menunjukkan bahwa suatu variabel adalah variabel yang dibuang dengan menetapkan karakter garis bawah (_
) sebagai namanya. Misalnya, panggilan metode berikut mengembalikan tuple di mana nilai pertama dan kedua dibuang.
area
adalah variabel yang dinyatakan sebelumnya yang diatur ke komponen ketiga yang dikembalikan oleh GetCityInformation
:
(_, _, area) = city.GetCityInformation(cityName);
Anda dapat menggunakan pembuangan untuk mendefinisikan parameter input yang tidak digunakan dalam ekspresi lambda. Untuk informasi selengkapnya, lihat bagian Parameter input ekspresi lambda dari artikel ekspresi Lambda .
Ketika _
adalah pelepasan yang valid, mencoba mengambil nilainya atau menggunakannya dalam operasi penugasan mengakibatkan error pengompilasi CS0103, "Nama '_' tidak ada dalam konteks saat ini". Kesalahan ini karena _
tidak diberi nilai, dan bahkan mungkin tidak ditetapkan lokasi penyimpanan. Jika itu adalah variabel aktual, Anda tidak dapat membuang lebih dari satu nilai, seperti contoh sebelumnya.
Dekonstruksi tuple dan objek
Pengabaian berguna dalam bekerja dengan tuple saat kode aplikasi Anda menggunakan beberapa elemen tuple namun mengabaikan elemen lainnya. Misalnya, metode berikut QueryCityDataForYears
mengembalikan tuple dengan nama kota, daerahnya, setahun, populasi kota untuk tahun itu, tahun kedua, dan populasi kota untuk tahun kedua tersebut. Contoh menunjukkan perubahan populasi antara dua tahun tersebut. Dari data yang tersedia dari tuple, kami tidak peduli dengan area kota, dan kami tahu nama kota dan dua tanggal pada waktu desain. Akibatnya, kami hanya tertarik pada dua nilai populasi yang disimpan dalam tuple, dan dapat menangani nilai yang tersisa sebagai buang.
var (_, _, _, pop1, _, pop2) = QueryCityDataForYears("New York City", 1960, 2010);
Console.WriteLine($"Population change, 1960 to 2010: {pop2 - pop1:N0}");
static (string, double, int, int, int, int) QueryCityDataForYears(string name, int year1, int year2)
{
int population1 = 0, population2 = 0;
double area = 0;
if (name == "New York City")
{
area = 468.48;
if (year1 == 1960)
{
population1 = 7781984;
}
if (year2 == 2010)
{
population2 = 8175133;
}
return (name, area, year1, population1, year2, population2);
}
return ("", 0, 0, 0, 0, 0);
}
// The example displays the following output:
// Population change, 1960 to 2010: 393,149
Untuk informasi selengkapnya tentang mendekonstruksi tuple dengan buang, lihat Mendekonstruksi tuple dan jenis lainnya.
Metode Deconstruct
kelas, struktur, atau antarmuka juga memungkinkan Anda untuk mengambil dan mendekonstruksi sekumpulan data tertentu dari objek. Anda dapat menggunakan pengabaian saat tertarik untuk bekerja dengan hanya sebagian dari nilai yang didekonstruksi. Contoh berikut mendekonstruksi Person
objek menjadi empat string (nama depan dan belakang, kota, dan status), tetapi membuang nama belakang dan status.
using System;
namespace Discards
{
public class Person
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string City { get; set; }
public string State { get; set; }
public Person(string fname, string mname, string lname,
string cityName, string stateName)
{
FirstName = fname;
MiddleName = mname;
LastName = lname;
City = cityName;
State = stateName;
}
// Return the first and last name.
public void Deconstruct(out string fname, out string lname)
{
fname = FirstName;
lname = LastName;
}
public void Deconstruct(out string fname, out string mname, out string lname)
{
fname = FirstName;
mname = MiddleName;
lname = LastName;
}
public void Deconstruct(out string fname, out string lname,
out string city, out string state)
{
fname = FirstName;
lname = LastName;
city = City;
state = State;
}
}
class Example
{
public static void Main()
{
var p = new Person("John", "Quincy", "Adams", "Boston", "MA");
// Deconstruct the person object.
var (fName, _, city, _) = p;
Console.WriteLine($"Hello {fName} of {city}!");
// The example displays the following output:
// Hello John of Boston!
}
}
}
Untuk informasi lebih lanjut tentang mendekonstruksi jenis yang didefinisikan pengguna dengan pembuangan, lihat Mendekonstruksi tuple dan jenis lainnya.
Pencocokan pola dengan switch
Pola buang dapat digunakan dalam pencocokan pola dengan ekspresi pengalihan. Setiap ekspresi, termasuk null
, selalu cocok dengan pola yang diabaikan.
Contoh berikut mendefinisikan ProvidesFormatInfo
metode yang menggunakan switch
ekspresi untuk menentukan apakah objek menyediakan IFormatProvider implementasi dan menguji apakah objek tersebut adalah null
. Ini juga menggunakan pola buang untuk menangani objek non-null dari jenis lain.
object?[] objects = [CultureInfo.CurrentCulture,
CultureInfo.CurrentCulture.DateTimeFormat,
CultureInfo.CurrentCulture.NumberFormat,
new ArgumentException(), null];
foreach (var obj in objects)
ProvidesFormatInfo(obj);
static void ProvidesFormatInfo(object? obj) =>
Console.WriteLine(obj switch
{
IFormatProvider fmt => $"{fmt.GetType()} object",
null => "A null object reference: Its use could result in a NullReferenceException",
_ => "Some object type without format information"
});
// The example displays the following output:
// System.Globalization.CultureInfo object
// System.Globalization.DateTimeFormatInfo object
// System.Globalization.NumberFormatInfo object
// Some object type without format information
// A null object reference: Its use could result in a NullReferenceException
Panggilan ke metode dengan parameter out
Saat memanggil Deconstruct
metode untuk mendekonstruksi jenis yang ditentukan pengguna (instans kelas, struktur, atau antarmuka), Anda dapat membuang nilai argumen individual out
. Tetapi Anda juga dapat membuang nilai out
argumen saat memanggil metode apa pun dengan out
parameter .
Contoh berikut memanggil metode DateTime.TryParse(String, out DateTime) untuk menentukan apakah representasi string tanggal valid dalam budaya saat ini. Karena contoh hanya berkaitan dengan memvalidasi string tanggal dan bukan dengan mengurainya untuk mengekstrak tanggal, argumen out
dari metode tersebut menjadi diabaikan.
string[] dateStrings = ["05/01/2018 14:57:32.8", "2018-05-01 14:57:32.8",
"2018-05-01T14:57:32.8375298-04:00", "5/01/2018",
"5/01/2018 14:57:32.80 -07:00",
"1 May 2018 2:57:32.8 PM", "16-05-2018 1:00:32 PM",
"Fri, 15 May 2018 20:10:57 GMT"];
foreach (string dateString in dateStrings)
{
if (DateTime.TryParse(dateString, out _))
Console.WriteLine($"'{dateString}': valid");
else
Console.WriteLine($"'{dateString}': invalid");
}
// The example displays output like the following:
// '05/01/2018 14:57:32.8': valid
// '2018-05-01 14:57:32.8': valid
// '2018-05-01T14:57:32.8375298-04:00': valid
// '5/01/2018': valid
// '5/01/2018 14:57:32.80 -07:00': valid
// '1 May 2018 2:57:32.8 PM': valid
// '16-05-2018 1:00:32 PM': invalid
// 'Fri, 15 May 2018 20:10:57 GMT': invalid
Pembuangan mandiri
Anda dapat menggunakan pengabaian mandiri untuk menunjukkan variabel apa pun yang Anda pilih untuk diabaikan. Salah satu penggunaan umumnya adalah menggunakan penugasan untuk memastikan bahwa argumen tidak null. Kode berikut menggunakan pembuangan untuk memaksa penetapan nilai. Sisi kanan penugasan menggunakan operator coalescing null untuk melempar saat System.ArgumentNullException argumen adalah null
. Kode tidak memerlukan hasil penugasan, sehingga dibuang. Ekspresi memaksa pengecekan null. Pembuangan menjelaskan niat Anda: hasil dari tugas tidak diperlukan atau digunakan lagi.
public static void Method(string arg)
{
_ = arg ?? throw new ArgumentNullException(paramName: nameof(arg), message: "arg can't be null");
// Do work with arg.
}
Contoh berikut menggunakan pembuangan secara mandiri untuk mengabaikan objek Task yang dikembalikan oleh operasi asinkron. Menetapkan tugas memiliki efek menghilangkan pengecualian yang dilemparkan oleh operasi saat akan diselesaikan. Ini membuat niat Anda jelas: Anda ingin membuang Task
, dan mengabaikan kesalahan apa pun yang dihasilkan dari operasi asinkron tersebut.
private static async Task ExecuteAsyncMethods()
{
Console.WriteLine("About to launch a task...");
_ = Task.Run(() =>
{
var iterations = 0;
for (int ctr = 0; ctr < int.MaxValue; ctr++)
iterations++;
Console.WriteLine("Completed looping operation...");
throw new InvalidOperationException();
});
await Task.Delay(5000);
Console.WriteLine("Exiting after 5 second delay");
}
// The example displays output like the following:
// About to launch a task...
// Completed looping operation...
// Exiting after 5 second delay
Tanpa menetapkan tugas ke variabel yang dibuang, kode berikut menghasilkan peringatan kompilator:
private static async Task ExecuteAsyncMethods()
{
Console.WriteLine("About to launch a task...");
// CS4014: Because this call is not awaited, execution of the current method continues before the call is completed.
// Consider applying the 'await' operator to the result of the call.
Task.Run(() =>
{
var iterations = 0;
for (int ctr = 0; ctr < int.MaxValue; ctr++)
iterations++;
Console.WriteLine("Completed looping operation...");
throw new InvalidOperationException();
});
await Task.Delay(5000);
Console.WriteLine("Exiting after 5 second delay");
Nota
Jika Anda menjalankan salah satu dari dua sampel sebelumnya menggunakan debugger, debugger akan menghentikan program saat pengecualian dilemparkan. Tanpa debugger terlampir, pengecualian diabaikan secara diam-diam dalam kedua kasus.
_
juga merupakan pengidentifikasi yang valid. Saat digunakan di luar konteks yang didukung, _
diperlakukan bukan sebagai buang tetapi sebagai variabel yang valid. Jika pengidentifikasi bernama _
sudah berada dalam cakupan, penggunaan _
sebagai pembuangan mandiri dapat mengakibatkan:
- Modifikasi nilai variabel dalam cakupan
_
yang tidak disengaja dengan menetapkannya nilai pembuangan yang dimaksudkan. Contohnya:private static void ShowValue(int _) { byte[] arr = [0, 0, 1, 2]; _ = BitConverter.ToInt32(arr, 0); Console.WriteLine(_); } // The example displays the following output: // 33619968
- Kesalahan kompilasi karena pelanggaran terhadap keamanan tipe. Contohnya:
private static bool RoundTrips(int _) { string value = _.ToString(); int newValue = 0; _ = Int32.TryParse(value, out newValue); return _ == newValue; } // The example displays the following compiler error: // error CS0029: Cannot implicitly convert type 'bool' to 'int'