8 marca 2017 by Tadeusz Balcer
Czytelniejszy kod C# dzięki argumentom nazwanym (ang. named arguments)
Standard C# 4.0 wprowadził tzw. argumenty nazwane (ang. named arguments), które pozwalają na identyfikowanie argumentów wywołania funkcji za pomocą nazw, a nie kolejności w definicji. Wyobraźmy sobie że mamy daną metodę:
public int Sum(int arg1, int arg2, int arg3) { return arg1 + arg2 + arg3; }
Możemy ją wywołać jawnie deklarując wartości dla argumentów, nie zwracając uwagi na ich kolejność:
int result = Add(arg2: 5, arg1: 4, arg3: 0) // returns 9
Możemy również pomieszać wywołanie argumentów z konkretnej pozycji z argumentami nazwanymi, o ile te drugie wystąpią na końcu:
int result = Add(5, arg2: 4, arg3: 0) // returns 9
Powyższy przykład nie przynosi jednak zbyt wielkich korzyści dla programisty czytającego ten kod. Wyobraźmy sobie jednak takie wywołanie metody:
SendHttpMessage(header, message, false);
O ile przeznaczenia dwóch pierwszych argumentów można się domyśleć, o tyle nie wiadomo, dlaczego przekazywana jest wartość false
. Powiedzmy że powyższe wywołanie tyczy się takiej metody:
public void SendHttpMessage(string header, string message, bool debug) { ... // some code here }
Korzystając z argumentów nazwanych, można tę metodę wywołać w taki sposób:
SendHttpMessage(header, message, debug: false);
Teraz przeglądając kod zawierający takie wywołanie, programista nie będzie musiał dodatkowo przeglądać definicje metody, aby w pełni ją zrozumieć. Argumenty nazwane doskonale sprawdzają się również przy definiowaniu warunków w testach jednostkowych. Wyobraźmy sobie taki test:
[Fact] public void Should_Properly_Calculate_Sum() { var sut = new PowerfulSum(); var result = sut.Sum(5, 5); Assert.Equal(result, 10); }
Na pierwszy rzut oka test wydaje się czytelny, nawet jest zmienna result
, dzięki której patrząc na metodę Assert.Equal()
wiemy, gdzie jest wynik działania. Jednak mija trochę czasu, zmieniamy kod, a tu nagle test nie przechodzi:
No to zaczynamy szukać błędu, może nie przyjrzeliśmy się samemu testowi, tylko zaczynamy od debugowania metody, idziemy krok po kroku, wynik operacji: 9. W opisie testu, wynik oczekiwany: 9. Gdzie jest błąd? Okazuje się że zgodnie z definicją metody Assert.Equal()
, argumenty powinny mieć odwrotną kolejność.
public void Assert.Equal<int>(int expected, int actual); </int>
Oczywiście, koniec końców uda nam się znaleźć błąd. Ale zwykłe przeoczenie i zaczynamy niepotrzebnie tracić czas. Można taki test zdefiniować nieco czytelniej:
[Fact] public void Should_Properly_Calculate_Sum() { var sut = new PowerfulSum(); var result = sut.Sum(5, 5); Assert.Equal(expected: 10, actual: result); }
Podsumowując, argumenty nazwane w wywołaniach metod mogą zwiększyć czytelność naszego kodu, co może przełożyć się na mniejszą liczbę błędów.
Bibliografia
- J. Albahari, B. Albahari, „C# 6.0 w pigułce. Wydanie VI”. 1. Wprowadzenie do C# i .NET Framework, s. 24
- Named and Optional Arguments (C# Programming Guide)