C# 4.0–parametry opcjonalne oraz named arguments

C# 4.0 dostarcza kilka nowych możliwości jeśli chodzi o parametry i ich przekazywanie. Pierwszym rozszerzeniem jest możliwość zdefiniowania opcjonalnych argumentów (dlaczego musieliśmy tak długo na to czekaćUśmiech?):

private void ShowText(string text="Hello world")
{
  MessageBox.Show(text);
}

Teraz możemy wywołać metodę ShowText dostarczając własny argument lub pomijać go i wykorzystując wartość domyślną (“Hello World”):

ShowText("Custom Text");
ShowText(); // również poprawne

Named arguments umożliwiają przekazanie parametrów do wywołania funkcji za pomocą ich nazwy (przekazywane wartości poprzedzamy nazwą parametru oraz dwukropkiem). Wyobraźmy sobie następującą funkcję:

private void ShowText(string text1, string text2 = "Hello world 2", string text3="Hello world3")
{
  MessageBox.Show(string.Format("text1:{0}", text1));
  MessageBox.Show(string.Format("text2:{0}", text2));
  MessageBox.Show(string.Format("text3:{0}", text3));
}

Jak przekazać funkcji wymagany parametr text1 oraz opcjonalny text3 a jednocześnie wykorzystać domyślną wartość text2? Poniższa próba zakończy się fiaskiem:

ShowText("text1", "text3");

text1 zostanie ustawiony na “text1” z kolei text2 na “text3” – a text3 posiadać będzie wartość domyślną czego nie chcemy. Z pomocą przychodzą wspomniane named arguments:

ShowText("text1", text3:"text3");

Zamiast przekazywać argumenty bazując na ich kolejności, wykorzystujemy po prostu ich nazwę. Ponadto jeśli nasza funkcja przyjmuje dużą liczbę parametrów (np. 5) warto skorzystać z named arguments aby za pomocą nazw wyjaśnić co te argumenty robią. Np. następująca funkcja na pierwszy rzut oka może niewiele mówić:

UpdateZoom(1,5,4);

Z kolei za pomocą named arguments możemy stworzyć samo-komentujący się kod:

UpdateZoom(minZoom:1,maxZoom:5,currentZoom:4);

Jak widać drugie wywołanie jest bardziej czytelne i więcej mówi o tym co funkcja wewnątrz robi.

Wróćmy na chwilę jeszcze do domyślnych argumentów. Opcjonalne wartości  zostały  wprowadzone również z myślą o COM. Wcześniej wdrożenie bibliotek COM do c# było czasami bardzo niewygodne. Klasy z COM mają bardzo dużo metod z wartościami domyślnymi, które zwykle nie są przekazywane przez programistę. Przykład (źródło MSDN):

Document d = new Document();
object filename = "Foo.docx";
object missing = Type.Missing;

d.SaveAs(ref filename, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);

W c# 4.0 kod uprości się do:

Document d = new Document();

d.SaveAs(FileName: "Foo.docx");

W bibliotekach .NET często widzimy wiele podobnych sygnatur różniących się tylko liczbą parametrów. Programiści w ten sposób (przeładowywaniem metod) radzili sobie z brakiem opcjonalnych argumentów. Od 4.0 możemy znaczącą skrócić kod, dostarczając wyłącznie jedną metodę ale za to z opcjonalnymi wartościami. Czyli zamiast:

private void ShowText(string text1)
{
  ShowText(text1, "Hello world 2", "Hello world 3");
}
private void ShowText(string text1,string text2)
{
  ShowText(text1, text2, "Hello world 3");
}
private void ShowText(string text1, string text2, string text3)
{
  MessageBox.Show(string.Format("text1:{0}", text1));
  MessageBox.Show(string.Format("text2:{0}", text2));
  MessageBox.Show(string.Format("text3:{0}", text3));
}

Wystarczy:

private void ShowText(string text1, string text2 = "Hello world 2", string text3="Hello world3")
{
  MessageBox.Show(string.Format("text1:{0}", text1));
  MessageBox.Show(string.Format("text2:{0}", text2));
  MessageBox.Show(string.Format("text3:{0}", text3));
}

4 thoughts on “C# 4.0–parametry opcjonalne oraz named arguments”

  1. Nic za darmo, od tej chwili nazwy argumentów funkcji stają się częścią API. Poprzednio w API wystarczały typy argumentów.

  2. Fajnie to wszystko opisałeś, ale jak to czytałem od razu przypomniało mi się słowo kluczowe params, o którym mogłeś dodać krótką wzmiankę, dzięki któremu do metody można wprowadzać nieograniczoną liczbę parametrów deklarując je jako tablicę parametrów.

  3. @artur:
    Ale params zostało wprowadzone przed c# 4.0 a post opisuje “nowości” w c# 4.0:)

  4. Rzeczywiście params zostało wprowadzone tak jak mówisz już dawno temu, ale tak jak mówiłem po prostu mi te dwie rzeczy skojarzyły i teraz już wiem czemu, w książce którą ostatnio czytałem “C# 4.0 IN A NUTSHELL” O’Reilly parametry params był bezpośrednio omówione przed parametrami opcjonalnymi:)Warto wiedzieć o obu tych rzeczach, pozdrawiam

Leave a Reply

Your email address will not be published.