Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Az elvetések olyan helyettesítő változók, amelyeket szándékosan nem használnak az alkalmazáskódban. Az elvetések egyenértékűek a nem hozzárendelt változókkal; nincs értékük. Az elvetés szándékot közöl a fordítóval és a kódot olvasó többi felhasználóval: Ön egy kifejezés eredményét figyelmen kívül szeretné hagyni. Előfordulhat, hogy figyelmen kívül szeretné hagyni egy kifejezés eredményét, egy vagy több tagot, egy metódus paraméterét out vagy egy mintamegfeleltetési kifejezés célját.
Az elvetések egyértelművé teszik a kód szándékát. Az elvetés azt jelzi, hogy a kód soha nem használja a változót. Javítják az olvashatóságot és a karbantarthatóságot.
Az elhagyás jelzésére egy változónál az aláhúzásjelet (_) rendeli a névként. A következő metódushívás például egy tupelt ad vissza, amelyben az első és a második értékek nincsenek felhasználva.
area egy korábban deklarált változó, amely be van állítva a GetCityInformation által visszaadott harmadik komponens értékére.
(_, _, area) = city.GetCityInformation(cityName);
A lambdakifejezések nem használt bemeneti paramétereit elvetések használatával adhatja meg. További információkért tekintse meg a Lambda-kifejezések cikk lambdakifejezés-szakaszánakbemeneti paramétereit.
Érvényes elvetés esetén _ , ha megkísérli lekérni az értékét, vagy egy hozzárendelési műveletben használni, cs0103-as fordítási hibát generál, "A_név nem létezik az aktuális környezetben". Ez a hiba azért van, mert _ nincs hozzárendelve érték, és lehet, hogy még tárolóhelyet sem rendel hozzá. Ha tényleges változóról van szó, nem lehet több értéket elvetni, mint az előző példában.
Tuple és objektum szétbontás
Az elemek figyelmen kívül hagyása akkor hasznos, amikor az alkalmazáskód n-tuplek bizonyos elemeit használja fel, de másokat figyelmen kívül hagy. Az alábbi QueryCityDataForYears módszer például egy tuple-t ad vissza, amely egy város nevét, annak területét, egy évszámot, a város lakosságát abban az évben, egy második évszámot és a város népességét a második évre vonatkozóan tartalmazza. A példa a két év közötti népességváltozást mutatja be. A rekordból elérhető adatok közül a városterülettel nem vagyunk tisztában, és tudjuk a város nevét és a két dátumot a tervezéskor. Ennek eredményeképpen csak a rekordban tárolt két sokaságérték érdekel minket, és a fennmaradó értékeket elvetésként tudja kezelni.
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
A tuplák elvetéssel történő dekonstruálásával kapcsolatos további információkért lásd a tuplák és más típusok dekonstruálását ismertető témakört.
Az Deconstruct osztály, a struktúra vagy az interfész metódusa lehetővé teszi egy adott adatkészlet lekérését és dekonstruálását is egy objektumból. Elvetéseket akkor használhat, ha csak a dekonstruált értékek egy részhalmazával szeretne dolgozni. Az alábbi példa egy objektumot négy sztringre Person (az utó- és vezetéknevekre, a városra és az államra) bont, de elveti a vezetéknevet és az államot.
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!
}
}
}
A felhasználó által definiált típusok eldobással történő bontásával kapcsolatos további információkért lásd: Deconstructing tuples and other types.
Mintaegyezés a switch
Az elvetési minta a kapcsolókifejezéssel egyező mintában használható. Minden kifejezés, beleértve a null-t, mindig egyezik az elvetési mintával.
Az alábbi példa meghatároz egy ProvidesFormatInfo metódust, amely egy switch kifejezést használ annak meghatározására, hogy egy objektum biztosít-e egy IFormatProvider implementációt, és ellenőrzi, hogy az objektum null-e. Emellett az elvetési mintát használja bármely más típusú nem null értékű objektumok kezelésére.
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
Metódusok meghívása paraméterekkel out
Ha meghívja a Deconstruct felhasználó által definiált típus (osztály, struktúra vagy felület egy példánya) dekonstruálásához a metódust, elvetheti az egyes out argumentumok értékeit. Azonban elvetheti az out argumentumok értékét, ha bármely metódust out paraméterrel hív meg.
Az alábbi példa meghívja a DateTime.TryParse(Sztring, out DateTime) metódust annak megállapításához, hogy egy dátum sztring-ábrázolása érvényes-e az aktuális kultúrában. Mivel a példa csak a dátumsztring érvényesítésével foglalkozik, és nem a dátum kinyeréséhez szükséges elemzéssel, a out metódus argumentuma elvetés.
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
Önálló elvetés
Önálló elvetés használatával jelezheti azokat a változót, amelyeket figyelmen kívül hagy. Általában egy hozzárendelés használatával biztosíthatja, hogy az argumentumok ne null értékűek legyenek. Az alábbi kód elvetés használatával kényszeríti a hozzárendelést. A hozzárendelés jobb oldala a null egyesítő operátort használja, hogy amikor az argumentum System.ArgumentNullException, egy null-t dobjon. A kódnak nincs szüksége a hozzárendelés eredményére, ezért el lesz vetve. A kifejezés null értékű ellenőrzést kényszerít ki. Az elvetés egyértelművé teszi a szándékot: a hozzárendelés eredménye nem szükséges vagy nem használható.
public static void Method(string arg)
{
_ = arg ?? throw new ArgumentNullException(paramName: nameof(arg), message: "arg can't be null");
// Do work with arg.
}
Az alábbi példa önálló elvetés használatával figyelmen kívül hagyja az Task aszinkron művelet által visszaadott objektumot. A feladat hozzárendelése letiltja a fordító figyelmeztetését a nem megengedett kivételekről. Az Ön szándéka világos: el szeretné vetni a Task elemet, és a hívók számára szeretné továbbadni az aszinkron műveletből eredő hibákat.
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
Ha a feladatot nem a „discard” nevű változóhoz rendeljük, a következő kód egy fordítói figyelmeztetést generál:
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");
Megjegyzés:
Ha az előző két minta valamelyikét egy hibakeresővel futtatja, a hibakereső leállítja a programot a kivétel kidobásakor. Hibakereső csatolása nélkül a kivételt mindkét esetben figyelmen kívül hagyja a rendszer.
_ is érvényes azonosító. Támogatott környezeten kívül történő használat esetén a rendszer nem elvetésként, _ hanem érvényes változóként kezeli. Ha egy _ azonosító már hatókörben van, a _ önmagában álló elvetésként a következőt eredményezheti:
- A hatókörön
_belüli változó értékének véletlen módosítása a tervezett elvetés értékének hozzárendelésével. Például:private static void ShowValue(int _) { byte[] arr = [0, 0, 1, 2]; _ = BitConverter.ToInt32(arr, 0); Console.WriteLine(_); } // The example displays the following output: // 33619968 - Fordítóhiba a típusbiztonság megsértése miatt. Például:
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'