piątek, 25 października 2019

Parametry opcjonalne i nazwane

Jak każdy wie, nie jest to żadna nowość gdyż parametry opcjonalne i nazwane zostały dodane do języka C# już w wersji 4.0 
W tym poście chciałbym wspomnieć o jednej pułapce, którą łatwo można przeoczyć. 

Parametry opcjonalne pozwalają nam pominąć podanie wartości dla argumentu oznaczonego jako opcjonalny. Parametry nazwana łączą parametry metody z wartością za pomocą nazwy (w tradycyjnym modelu możemy przyjąć, że argumenty metody łączone są z wartościami kolejnością przesłanych parametrów).

    class Program
    {
        static void Main(string[] args)
        {
            var customer = CreateCustomer(); //all parameters will be 
            var customer1 = CreateCustomer("Patryk"); //assign only firstName, rest of parameters (optional) will be assigned with empty value
            var customer2 = CreateCustomer(email: "patryk.osowski@someemail.com"); //assign only email
            var customer3 = CreateCustomer(address: "Krakow, Wadowicka 4", firstName: "Sebastian", lastName: "Kowalski"); //assign address, firstName and lastName
        }

        public static Customer CreateCustomer(string firstName = "", string lastName = "", string address = "", string email = "")
        {
            return new Customer {FirstName = firstName, LastName = lastName, Address = address, Email = email};
        }
    }

    public class Customer
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Address { get; set; }
        public string Email { get; set; }
    }

Powyżej przykład wywołania który zapewne każdy z was widział i pewnie stosuje. 

Gdzie można stosować parametry nazwane i/lub opcjonalne? W metodach, indekserach, konstruktorach oraz delegatach. 

Jakie wartości można przypisywać w deklaracji typu wartościowego? Dozwolone wartości:
  • stałe wyrażenie, czyli wartość która może zostać wyliczona podczas kompilacji
  • element typu wyliczeniowego
  • wartość domyślna (string firstName = default)
Jeżeli zostanie użyte wyrażenie, które wymaga uruchomienia programu w celu jego obliczenie - kompilator zgłosi błąd podczas budowania projektu. 

Parametry opcjonalne nie mogą mieszać się z parametrami wymaganymi. W deklaracji sygnatury metody muszą występować na końcu. 

Można zadać pytanie - czy opcjonalne / nazwane parametry mają jakikolwiek wpływ na wydajność aplikacji? Nie mają. Kompilator podczas budowania kodu niejako "wrzuci" wartości w wywołanie metody. Z powyższego wynika jedna pułapka na, którą warto uważać. Najlepiej przedstawi to poniższy przykład:


Tworzymy dwa projekty - pierwszy to zwykła aplikacja konsolowa, druga to biblioteka z jedną klasą np. Sample jak w tym przypadku. Klasa Sample posiada jedną metodę z opcjonalnym parametrem:

using System;

namespace OptionalParameterAssembly
{
    public class Sample
    {
        public void PrintDefaultValue(int value = 5)
        {
            Console.WriteLine(value);
        }
    }
}

Aplikacja konsolowa posiada referencję do biblioteki i wywołuje metodę PrintDefaultValue:

            var sample = new Sample();
            sample.PrintDefaultValue();

Po uruchomieniu aplikacji nie zobaczymy nic nadzwyczajnego - zostanie wyświetlona wartość 5:


Przejdźmy do sedna: Zmieńmy wartość domyślną w naszej bibliotece i skompilujmy tylko ją. Następnie skopiujmy ją do aplikacji konsolowej:

        public void PrintDefaultValue(int value = 10)
        {
            Console.WriteLine(value);
        }







Jak myślicie co zostanie wyświetlone na ekranie po uruchomieniu OptionalNamedParameters.exe?


Dokładnie 5! Opcjonalne parametry łączone są z metodą w momencie kompilacji programu. Jeżeli więc używamy biblioteki i zawiera ona opcjonalne metody, należy zawsze pamiętać o skompilowaniu głównej aplikacji po zmianach w bibliotece. 

Brak komentarzy:

Prześlij komentarz