Zauważyłem, że przy opcjonalnych parametrach w C # 4, jeśli podasz opcjonalny parametr w interfejsie, którego nie używasz , musisz uczynić ten parametr opcjonalnym dla dowolnej klasy implementującej:
public interface MyInterface
{
void TestMethod(bool flag = false);
}
public class MyClass : MyInterface
{
public void TestMethod(bool flag)
{
Console.WriteLine(flag);
}
}
i dlatego:
var obj = new MyClass();
obj.TestMethod(); // compiler error
var obj2 = new MyClass() as MyInterface;
obj2.TestMethod(); // prints false
Czy ktoś wie, dlaczego parametry opcjonalne zostały zaprojektowane w taki sposób?
Z jednej strony przypuszczam, że możliwość przesłonięcia wartości domyślnych określonych w interfejsach jest przydatna, ale szczerze mówiąc, nie jestem pewien, czy powinieneś być w stanie określić wartości domyślne w interfejsie, ponieważ powinna to być decyzja implementacyjna.
Z drugiej strony to rozłączenie oznacza, że nie zawsze można używać zamiennie konkretnej klasy i interfejsu. To oczywiście nie stanowiłoby problemu, jeśli wartość domyślna jest podana w implementacji, ale jeśli ujawniasz swoją konkretną klasę jako interfejs (używając na przykład niektórych struktur IOC do wstrzyknięcia konkretnej klasy), to naprawdę nie ma punkt o wartości domyślnej, ponieważ dzwoniący zawsze musi ją podać.
MyInterface
i wywołać ją z opcjonalnego parametru:((MyInterface)obj).TestMethod();
.Odpowiedzi:
AKTUALIZACJA: To pytanie było przedmiotem mojego bloga w dniu 12 maja 2011 r. Dzięki za świetne pytanie!
Załóżmy, że masz opisany interfejs i sto klas, które go implementują. Następnie zdecydujesz, aby jeden z parametrów jednej z metod interfejsu był opcjonalny. Czy sugerujesz, że właściwą rzeczą jest, aby kompilator zmusił programistę do znalezienia każdej implementacji tej metody interfejsu i uczynił parametr również opcjonalnym?
Załóżmy, że to zrobiliśmy. Załóżmy teraz, że programista nie miał kodu źródłowego dla implementacji:
Jak autor D ma to zrobić? Czy są wymagane w twoim świecie, aby zadzwonić do autora B przez telefon i poprosić go o dostarczenie nowej wersji B, która sprawia, że metoda ma opcjonalny parametr?
To nie będzie latać. Co jeśli dwie osoby wywołują autora B, a jedna z nich chce, aby domyślna była prawdziwa, a jedna z nich chce, aby była fałszywa? Co jeśli autor B po prostu odmawia gry?
Być może w takim przypadku musieliby powiedzieć:
Proponowana funkcja wydaje się powodować wiele niedogodności dla programisty bez odpowiedniego wzrostu mocy reprezentatywnej. Jakie są zalety tej funkcji, które uzasadniają wzrost kosztów dla użytkownika?
AKTUALIZACJA: W poniższych komentarzach supercat sugeruje funkcję językową, która naprawdę dodałaby moc do języka i umożliwiła niektóre scenariusze podobne do opisanych w tym pytaniu. Do Twojej dyspozycji ta funkcja - domyślne implementacje metod w interfejsach - zostanie dodana do C # 8.
źródło
Opcjonalny parametr jest właśnie oznaczony atrybutem. Ten atrybut mówi kompilatorowi, aby wstawił wartość domyślną tego parametru w miejscu wywołania.
Wywołanie
obj2.TestMethod();
zostaje zastąpione przezobj2.TestMethod(false);
kompilację kodu C # do IL, a nie w czasie JIT.Tak więc w pewnym sensie zawsze dzwoniący podaje wartość domyślną z opcjonalnymi parametrami. Ma to również konsekwencje dla wersji binarnej: jeśli zmienisz wartość domyślną, ale nie przekompilujesz kodu wywołującego, nadal będzie używać starej wartości domyślnej.
Nie możesz tego zrobić, jeśli metoda interfejsu została zaimplementowana jawnie .
źródło
Ponieważ parametry domyślne są rozwiązywane w czasie kompilacji, a nie w czasie wykonywania. Zatem wartości domyślne nie należą do wywoływanego obiektu, ale do typu odwołania, przez który jest on wywoływany.
źródło
Z tego, co rozumiem, parametry opcjonalne są jak podstawienie makr. Nie są tak naprawdę opcjonalne z punktu widzenia metody. Artefaktem tego jest zachowanie, które widać, gdy uzyskuje się różne wyniki po rzutowaniu na interfejs.
źródło