c# 7.0 – operator Is, część druga

Ostatnio przyjrzeliśmy się pierwszemu usprawnieniu operatora IS. Tak naprawdę jest to część dużo większej zmiany, a mianowicie dopasowywania wzorców (pattern matching). Celem jest filtracja i wyodrębnianie konkretnych danych z obiektu. Dla osób znających programowanie funkcyjne,  nie stanowi to prawdopodobnie wielkiej zmiany. Język C# zawiera coraz więcej elementów programowania funkcyjnego,  przy tym samym zachowując swój styl zaczerpnięty  z CPP i klasycznych języków obiektowych.

W ostatnim poście opisałem tzw. “type pattern” ponieważ wydobywaliśmy dane na podstawie typu. Operator zwracał “true”, gdy typ był zgodny z naszymi oczekiwaniami:

object test = 5;
 
if(test is int integerValue)
{
    Console.WriteLine(integerValue.GetType());
    Console.WriteLine(integerValue * 5);
}

Kolejnym rodzajem wzorca jest “var pattern”:

            object test = 5;

            if (test is var x)
            {
                Console.WriteLine(x.GetType());
            }

Wzorzec “var” zwraca zawsze true. Oznacza to, że instrukcja IF zawsze wykona się. Na ekranie w powyższym przypadku wyświetli się “System.Int32”. Zmienna x jednak jest typu System.Object, zatem nie możemy wykonać na niej bezpośrednio operacji arytmetycznych. Po kompilacji, powyższa konstrukcja wygląda następująco:

                        object test = 5;
			object x = test;
			bool flag = true;
			if (flag)
			{
				Console.WriteLine(x.GetType());
			}

Wiem, że na razie wygląda to bezużytecznie, ale w przyszłym poście zajmiemy się rekurencyjnymi wzorcami i wtedy znajduje to zastosowanie.

Kolejny wzorzec to “wildcard pattern”:

             object test = 5;

            if (test is *)
            {
                Console.WriteLine(test.GetType());
            }

Na ekranie oczywiście znów wyświetli się System.Int32. Analogicznie jak wzorzec var, zawsze zwraca true. Jedyna różnica to fakt, że w przypadku wildcard, nie wydobywamy żadnych danych. Po dekompilacji zobaczymy po prostu:

object test = 5;
Console.WriteLine(test.GetType());

Następny wzorzec to “const pattern”, czyli dopasowywanie stałych. Przydaje się np. w instrukcji switch. Przykład:

            object test = 3;

            switch (test)
            {
                case int integerValue when integerValue <= 5:
                    Console.WriteLine(integerValue );
                    break;

                case int integerValue:
                    Console.WriteLine(integerValue * 5);
                    break;
                case string text:
                    Console.WriteLine(text.ToLower());
                    break;
                case *:
                    Console.WriteLine("All");
                    break;
            }

W powyższym przykładzie, dopasowywanie zostało umieszczone w instrukcjach warunkowych CASE. Normalnie, switch porównuje dane za pomocą operatora ==. W c# 7.0 wspiera on dopasowywanie wzorców i w powyższym kodzie skorzystaliśmy ze wzorca “Type” oraz “wildcard”. Ponadto dodano klauzule “when”, gdzie możemy filtrować dodatkowo wartości. Powyższy kod, pokazuje również, że w pewnych sytuacjach, zarówno “wildcard” jak i “var pattern” są przydatne. Oczywiście nie korzystamy z nich jak mamy pojedynczą instrukcję warunkową, ale w przypadku switch jest już to realny przykład użycia.

Po dekompilacji otrzymamy:

	internal class Program
	{
		private static void Main(string[] args)
		{
			object test = 3;
			object obj = test;
			int? num = obj as int?;
			int integerValue = num.GetValueOrDefault();
			if (num.HasValue && integerValue <= 5)
			{
				Console.WriteLine(integerValue);
			}
			else
			{
				num = (obj as int?);
				int integerValue2 = num.GetValueOrDefault();
				if (num.HasValue)
				{
					Console.WriteLine(integerValue2 * 5);
				}
				else
				{
					string text = obj as string;
					if (text != null)
					{
						Console.WriteLine(text.ToLower());
					}
					else
					{
						Console.WriteLine("All");
					}
				}
			}
		}
	}

W przyszłym poście przyjrzymy się rekurencyjnemu dopasowywaniu, które stanowi agregację przedstawionych wzorców.

Leave a Reply

Your email address will not be published.