2009-07-31 8 views
6

Zacząłem czytać wcześniej dostępną wersję Jona Skeeta z jego książki, która zawiera sekcje na C# 4.0, i jedno mnie uderzyło. Niestety nie mam dostępnego Visual Studio 2010, więc pomyślałem, że zamiast tego zapytam tutaj i zobaczę, czy ktoś zna odpowiedź.Czy C# 4.0 i kombinacja opcjonalnych parametrów i przeciążeń daje ostrzeżenie o niejasności?

Jeśli mam następujący kod, mieszaninę istniejącego kodu i nowy kod:

public void SomeMethod(Int32 x, Int32 y) { ... } 

public void SomeMethod(Int32 x, Int32 y, Int32 z = 0) { ... } 

Czy kompilator narzekać albo w miejscu definicji lub w miejscu połączenia o możliwej dwuznaczności?

Na przykład, co właściwie zrobi ten fragment kodu?

SomeClass sc = new SomeClass(); 
sc.SomeMethod(15, 23); 

Czy to się skompiluje? Czy wywoła tę bez parametru z, czy też wywoła tę z parametrem z?

+0

Pozostawiając to konkretne pytanie na bok, Byłbym bardzo zadowolony z otrzymywania innych informacji zwrotnych na temat nowych rozdziałów - za pośrednictwem podobnych pytań lub bezpośrednio za pośrednictwem poczty elektronicznej ([email protected]).Mam nadzieję, że spodoba ci się nowy materiał :) –

+0

Idę przeczytać plik, który pobrałem, zanim wyślę więcej informacji zwrotnych lub pytań;) Ale tak, chętnie udzielę informacji zwrotnej. W weekend zabieram plik do domu bez internetu, więc pewnie go zagłębię. –

Odpowiedz

6

Zostanie skompilowany bez ostrzeżeń i wybierze pierwsze przeciążenie.

Wraz z wprowadzeniem opcjonalnych i nazwanych parametrów, mechanizm rozwiązywania przeciążenia C# stał się naprawdę skomplikowany. W tym konkretnym przypadku ma jednak sens. Jak zwykle, kompilator wybierze najbardziej specyficzne przeciążenie, które pasuje do argumentów.

nie wierzę, to specyficzny przypadek jest znacznie różni się od C# 1.0:

public void SomeMethod(Int32 x, Int32 y) { } 
public void SomeMethod(Int32 x, Int32 y, params Int32[] z) { } 

która działa identycznie (pod względem rozdzielczości przeciążenia).

Powtórz odpowiedź: Nie sądzę. Obawiam się, że będziesz musiał ręcznie określić domyślny argument w wywołaniu metody. Jednakże, jeśli x lub y parametr miał inną nazwę jak:

public void SomeMethod(Int32 x, Int32 y) { } 
public void SomeMethod(Int32 t, Int32 y, Int32 z = 0) { } 

można wybrać drugi z przeciążenia:

obj.SomeMethod(t: 10, y: 20); 
+1

Pytanie uzupełniające: czy istnieje sposób na wywołanie drugiego przeciążenia bez określania parametru 'z'? – Blixt

9

to jest opisane w sekcji „Rozwiązanie” Przeciążenie rozdziału.

Gdy kompilator ma do wyboru dwie opcje o jednakowej wartości, użyje przeciążenia, które nie wymaga użycia niepotrzebnych parametrów opcjonalnych zamiast tego, który ma, ale jest to ścisły wybór binarny. Jeśli ma do wyboru między przeciążeniem a jednym opcjonalnym parametrem opcjonalnym i dwoma, uzna to za niejednoznaczną sytuację.

Aby odpowiedzieć na twój komentarz uzupełniający, nie wiem, jak wymusić przeciążenie z opcjonalnym parametrem, który ma być używany bez określania go. Nie można użyć jednej z nich, na przykład:

// Both invalid 
sc.SomeMethod(15, 23,); 
sc.SomeMethod(15, 23, z:) 

Jeśli jednak twoje metody stosowane różne nazwy parametru, mógłby zrobić wtedy:

public void SomeMethod(Int32 x, Int32 y) { ... } 
public void SomeMethod(Int32 a, Int32 b, Int32 c = 0) { ... } 

sc.SomeMethod(a: 15, b: 23); // Calls second method 
+0

Służy mi prawo do skoku modą :) –

Powiązane problemy