Ostatnio chciałem dodać opcjonalny parametr do metody rozszerzenia. Oryginalna metoda wyglądała następująco:Metoda C# z domyślną wartością parametru nie generuje przeciążenia bez parametru?
public static class Extensions {
public static bool Foo(this IFoo target) {
target.DoIt(true);
}
}
Jest to oczywiście wersja uproszczona, ale odejdźmy od tego.
Co zrobiłem to:
public static class Extensions {
public static bool Foo(this IFoo target, bool flag = true) {
target.DoIt(flag);
}
}
Wszystko zrobiłem jest wprowadzenie opcjonalnego parametru z wartością domyślną, prawda? Spodziewałem się kompilatora generującego przeciążoną metodę bez flagi. To się częściowo zdarzyło. Każdy kod że zrekompilowane mógł skompilować i wykonać bez żadnych problemów, nawet bez parametru jak ten:
...
IFoo foo = new FooBar();
foo.Foo();
...
jednak żadnego kodu, który został zbudowany na poprzedniej wersji Foo() nie działa, rzucając następujący wyjątek:
Unhandled Exception: System.MissingMethodException: Method not found: 'Boolean Models.Class1.Foo()'.
at DefaultParamsTests.Program.Main(String[] args)
jest to oczywiście problem dla nas, jak mamy API publiczną, że nasi klienci zrobić dźwigni i byłoby to łamanie zmiana.
Rozwiązaniem jest jawnie utworzyć przeciążeniem:
public static class Extensions {
public static bool Foo(this IFoo target) {
target.DoIt(true);
}
public static bool Foo(this IFoo target, bool) {
target.DoIt(true);
}
}
Jednak Resharper sugeruje, że mogę wprowadzić opcjonalny parametr dla metody foo.
Jeśli będę postępować zgodnie z refactoring to w zasadzie robi to, co pokazałem powyżej. To jednak nie zadziała w przypadku istniejącego kodu.
I spojrzał na wygenerowanym przy użyciu zarówno IL reflektor i dotPeek. Żadne nie pokazuje generacji przeciążenia.
Czego mi brakuje?
Co powoduje ci wierzyć, że kompilator będzie generować dwa przeciążenia metody dla pojedynczej deklaracji? – gknicker
Myślę, że już odpowiedziałeś na swoje pytanie. Czy możesz po prostu dodać tę metodę i zignorować sugestię Resharpera, aby wprowadzić opcjonalny parametr? – maxwellb
@gknicker, oczywiście, gdzieś powstaje przeciążenie. W przeciwnym razie parametry domyślne nie działałyby. Jak wskazały dwie osoby, które odpowiedziały na to pytanie, zakładałem, że zostało wygenerowane w niewłaściwym miejscu. Wartość domyślna jest wstrzykiwana przez kompilator w miejscu wywołania zamiast w miejscu deklaracji. –