Odrzuca — Przewodnik po języku C#Discards - C# Guide

Począwszy od języka C# 7.0, C# obsługuje odrzuca, służą do tymczasowego, fikcyjnego zmiennych, które są celowo nieużywane w kodzie aplikacji.Starting with C# 7.0, C# supports discards, which are temporary, dummy variables that are intentionally unused in application code. Odrzuca są równoważne nieprzypisane zmiennych; nie mają wartości.Discards are equivalent to unassigned variables; they do not have a value. Ponieważ jest zmienną pojedynczego odrzucenia, a tej zmiennej nie może jeszcze być alokowana magazynu, odrzucenia może zmniejszyć alokacji pamięci.Because there is only a single discard variable, and that variable may not even be allocated storage, discards can reduce memory allocations. Ponieważ ich zamiar zwykłego kodu, zwiększyć jego czytelność i łatwość konserwacji.Because they make the intent of your code clear, they enhance its readability and maintainability.

Można wskazać, że zmienna jest odrzucenia, przypisując go znak podkreślenia (_) jako jego nazwę.You indicate that a variable is a discard by assigning it the underscore (_) as its name. Na przykład, następujące wywołanie metody zwraca 3-krotka, w którym wartości pierwszego i drugiego to odrzutów i obszaru poprzednio zadeklarowana zmienna, należy ustawić odpowiadającego składnika trzeciej zwrócony przez GetCityInformation:For example, the following method call returns a 3-tuple in which the first and second values are discards and area is a previously declared variable to be set to the corresponding third component returned by GetCityInformation:

(_, _, area) = city.GetCityInformation(cityName);

W języku C# 7.0 odrzucenia są obsługiwane w przypisania w następujących okolicznościach:In C# 7.0, discards are supported in assignments in the following contexts:

  • Krotki i obiekt dekonstrukcja.Tuple and object deconstruction.
  • Za pomocą dopasowywania do wzorca jest i Przełącz.Pattern matching with is and switch.
  • Wywołania do metod z out parametrów.Calls to methods with out parameters.
  • Autonomiczny _ gdy nie _ znajduje się w zakresie.A standalone _ when no _ is in scope.

Gdy _ jest prawidłowy odrzucenia próby pobrania jej wartość lub użyj jej w operacji przypisania generuje błąd kompilatora CS0301, "Nazwa"_"nie istnieje w bieżącym kontekście".When _ is a valid discard, attempting to retrieve its value or use it in an assignment operation generates compiler error CS0301, "The name '_' does not exist in the current context". Jest to spowodowane _ nie jest przypisywana wartość i nie może jeszcze być przypisany lokalizacji magazynu.This is because _ is not assigned a value, and may not even be assigned a storage location. W przypadku rzeczywista zmienna, nie może odrzucić więcej niż jedną wartość, tak jak w poprzednim przykładzie.If it were an actual variable, you could not discard more than one value, as the previous example did.

Dekonstrukcja krotki i obiektuTuple and object deconstruction

Odrzuca są szczególnie przydatne w pracy z krotek, gdy kod aplikacji używa niektórych elementów krotki, ale ignoruje inne osoby.Discards are particularly useful in working with tuples when your application code uses some tuple elements but ignores others. Na przykład następująca QueryCityDataForYears metoda zwraca 6-krotka nazwą miasta, jego obszaru, roku, to miasto populację na potrzeby tego roku, drugiego roku i miasta populację na potrzeby tego drugiego roku.For example, the following QueryCityDataForYears method returns a 6-tuple with the name of a city, its area, a year, the city's population for that year, a second year, and the city's population for that second year. W przykładzie pokazano zmianę populacji między te dwa lata.The example shows the change in population between those two years. Dane udostępniła spójnej kolekcji, jesteśmy unconcerned z obszarem miasta i wiemy, nazwę miasta i dwiema datami w czasie projektowania.Of the data available from the tuple, we're unconcerned with the city area, and we know the city name and the two dates at design-time. W rezultacie firma Microsoft interesują jedynie wartości dwóch populacji, przechowywane w spójnej kolekcji i może obsługiwać jego pozostałe wartości jako odrzucenia.As a result, we're only interested in the two population values stored in the tuple, and can handle its remaining values as discards.

using System;
using System.Collections.Generic;

public class Example
{
   public static void Main()
   {
       var (_, _, _, pop1, _, pop2) = QueryCityDataForYears("New York City", 1960, 2010);

       Console.WriteLine($"Population change, 1960 to 2010: {pop2 - pop1:N0}");
   }
   
   private 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

Aby uzyskać więcej informacji na temat dekonstrukcja krotek przy użyciu odrzucenia, zobacz Dekonstrukcja krotek i innych typów.For more information on deconstructing tuples with discards, see Deconstructing tuples and other types.

Deconstruct Metody klasy, struktury lub interfejsu umożliwia również pobrać i dekonstruować określonego zestawu danych z obiektu.The Deconstruct method of a class, structure, or interface also allows you to retrieve and deconstruct a specific set of data from an object. Możesz użyć odrzucenia, jeśli interesują Cię Praca z podzbiorem śródwierszową wartości.You can use discards when you are interested in working with only a subset of the deconstructed values. Poniższy przykład deconstructs Person obiektu do czterech ciągów (imiona i nazwiska, miasta i stanu), ale odrzuca nazwisko i stanu.The following example deconstructs a Person object into four strings (the first and last names, the city, and the state), but discards the last name and the state.

using System;

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;
   }                           
}

public class Example
{
   public static void Main()
   {
       Person p = new Person("John", "Quincy", "Adams", "Boston", "MA");

       // <Snippet1>
       // Deconstruct the person object.
       var (fName, _, city, _) = p;
       Console.WriteLine($"Hello {fName} of {city}!");
       // The example displays the following output:
       //      Hello John of Boston!       
       // </Snippet1>
   }
}
// The example displays the following output:
//    Hello John Adams of Boston, MA!

Aby uzyskać więcej informacji na temat dekonstrukcja typy zdefiniowane przez użytkownika przy użyciu odrzucenia, zobacz Dekonstrukcja krotek i innych typów.For more information on deconstructing user-defined types with discards, see Deconstructing tuples and other types.

Za pomocą dopasowywania do wzorca switch i isPattern matching with switch and is

Odrzucić wzorzec mogą być używane w dopasowywania do wzorca z jest i Przełącz słów kluczowych.The discard pattern can be used in pattern matching with the is and switch keywords. Każde wyrażenie zawsze zgodny ze wzorcem odrzucenia.Every expression always matches the discard pattern.

W poniższym przykładzie zdefiniowano ProvidesFormatInfo metody, która używa jest instrukcje, aby określić, czy zawiera obiekt IFormatProvider implementacji i testów czy obiekt jest null.The following example defines a ProvidesFormatInfo method that uses is statements to determine whether an object provides an IFormatProvider implementation and tests whether the object is null. Używa również wzorca odrzucania obsługi obiektów innych niż null innego typu.It also uses the discard pattern to handle non-null objects of any other type.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      object[] objects = { CultureInfo.CurrentCulture, 
                           CultureInfo.CurrentCulture.DateTimeFormat, 
                           CultureInfo.CurrentCulture.NumberFormat,
                           new ArgumentException(), null };
      foreach (var obj in objects)
         ProvidesFormatInfo(obj);
   }

   private static void ProvidesFormatInfo(object obj)         
   {
      if (obj is IFormatProvider fmt)
         Console.WriteLine($"{fmt} object");
      else if (obj is null) {
         Console.Write("A null object reference: ");
         Console.WriteLine("Its use could result in a NullReferenceException");
      }
      else
         Console.WriteLine($"Some object type without format information");
   }
}
// The example displays the following output:
//    en-US 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

Wywołania metod za pomocą parametrów outCalls to methods with out parameters

Podczas wywoływania Deconstruct metody typu zdefiniowanego przez użytkownika (wystąpienia klasy, struktury lub interfejsu), możesz odrzucić wartości poszczególnych dekonstruować out argumentów.When calling the Deconstruct method to deconstruct a user-defined type (an instance of a class, structure, or interface), you can discard the values of individual out arguments. Ale można również odrzucić wartość out argumentów podczas wywoływania dowolnej metody z parametrem out.But you can also discard the value of out arguments when calling any method with an out parameter.

Poniższy przykład wywołuje DateTime.TryParse (ciąg, out daty/godziny) metodę, aby określić, czy reprezentacją ciągu daty jest nieprawidłowy w bieżącej kultury.The following example calls the DateTime.TryParse(String, out DateTime) method to determine whether the string representation of a date is valid in the current culture. Ponieważ przykład dotyczy tylko w przypadku sprawdzania poprawności ciągu daty i nie ich w celu wyodrębnienia Data, analizowania out argument do metody jest odrzucenia.Because the example is concerned only with validating the date string and not with parsing it to extract the date, the out argument to the method is a discard.

using System;

public class Example
{
   public static void Main()
   {
      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

Odrzuć autonomicznyA standalone discard

Odrzucenia autonomiczny służy do wskazania jakakolwiek zmienna, która zostanie zignorowany.You can use a standalone discard to indicate any variable that you choose to ignore. W poniższym przykładzie użyto odrzucenia autonomiczne do ignorowania Task obiektu zwróconego przez operację asynchroniczną.The following example uses a standalone discard to ignore the Task object returned by an asynchronous operation. Skutkuje to pomijania wyjątek, który zgłasza operacji, jak zbliża się zakończyć.This has the effect of suppressing the exception that the operation throws as it is about to complete.

using System;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      ExecuteAsyncMethods().Wait();
   }

   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

Należy pamiętać, że _ jest również prawidłowym identyfikatorem.Note that _ is also a valid identifier. Gdy jest używana poza kontekstem obsługiwanych, _ jest traktowany jako prawidłową zmienną, ale nie jako odrzucenia.When used outside of a supported context, _ is treated not as a discard but as a valid variable. Jeśli nazwany identyfikator _ jest już w zakresie użytkowania _ jako autonomiczny odrzucenia może doprowadzić do:If an identifier named _ is already in scope, the use of _ as a standalone discard can result in:

  • Przypadkowe modyfikacji wartości w zakresie _ zmiennej, przypisując jej wartość zamierzony odrzucenia.Accidental modification of the value of the in-scope _ variable by assigning it the value of the intended discard. Na przykład:For example:

    private static void ShowValue(int _)
    {
       byte[] arr = { 0, 0, 1, 2 };
       _ = BitConverter.ToInt32(arr, 0);
       Console.WriteLine(_);
    }
    // The example displays the following output:
    //       33619968
    
  • Błąd kompilatora za naruszenie bezpieczeństwa typu.A compiler error for violating type safety. Na przykład:For example:

    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'   
    
  • Błąd kompilatora CS0136, "element lokalny lub parametr o nazwie"_"nie można zadeklarować w tym zakresie, ponieważ w tym nazwa jest używana w otaczającym zakresie lokalnym do zdefiniowania elementu lokalnego lub parametru."Compiler error CS0136, "A local or parameter named '_' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter." Na przykład:For example:

    public void DoSomething(int _) 
    {
     var _ = GetValue(); // Error: cannot declare local _ when one is already in scope
    }   
    // The example displays the following compiler error:
    // error CS0136: 
    //       A local or parameter named '_' cannot be declared in this scope 
    //       because that name is used in an enclosing local scope 
    //       to define a local or parameter   
    

Zobacz takżeSee also