2009-05-24 17 views
5

Mam następujący wzór modelu:Czy istnieje sposób przeciążania metod rozszerzeń w C#?

public abstract class PARENTCLASS {...} 
public class CHILD_A_CLASS : PARENTCLASS{...} 
public static class EXTENSION{ 
    public static METHOD(this PARENTCLASS parent){...} 
    public static METHOD(this CHILD_A_CLASS child) {...} 
} 

Coś jak powyżej, oczywiście będzie więcej dziecko (i wnuk) klas, ale ja po prostu umieścić jeden z nich. Problemem jest to, kiedy nazywa się metodę rozszerzenia tak:

PARENTCLASS cc = new CHILD_A_CLASS(); 
cc.METHOD(); 

To będzie wykonywał rodzic metodę rozszerzenia zamiast moja oczekiwano metodę rozszerzenia dziecka. Ktoś ma pomysł, jak to wdrożyć? (Nie zastanawiam się nad wprowadzeniem METHOD do klasy i pozwolić mu na dziedziczenie, ponieważ chcę zachować czystość klasy modelu i odejść od innej logiki).

Odpowiedz

5

Z pewnością możliwe jest przeciążenie przeciążenia metod rozszerzenia. Twój kod jest przykładem tego, jak to zrobić.

To, co wydaje się być pożądane, to możliwość nadpisania nadpisania metod rozszerzenia w taki sposób, że typ środowiska wykonawczego obiektu będzie określał wywołanie metody Extension. Podobnie jak definiowanie wirtualnej metody na klasie. Nie ma specyficznej obsługi składni języka dla takiej funkcji.

Jeśli to naprawdę ważne, możesz ręcznie zaimplementować tę funkcję. Wymaga odrobiny brutalnej siły, ale wykona to zadanie. Na przykład ...

public static class Extension { 
    public static void Method(this ParentClass p) { 
    var c = p as ChildAClass; 
    if (c != null) { 
     Method(c); 
    } else { 
     // Do parentclass action 
    } 
    } 
    public static void Method(this ChildAClass c) { 
    ... 
    } 
} 
+0

Dzięki. Myślę, że odlewanie typu byłoby zbyt kosztowne do wykonania, a także dość niezdarne, aby utrzymać kod w ten sposób. Myślę, że szukałbym alternatywnej metody wdrożenia tego. – xandy

+1

Odlewanie typów jest dość szybkie, choć może być trudne do utrzymania. –

+0

Twoja propozycja nie jest polimorficzna, wybrana metoda jest poprawna tylko dla typu odwołania do kompilacji, a nie dla typu środowiska wykonawczego. Mówiąc krótko, nie jest to prawda nadrzędna - uważam, że jest to zła praktyka, ponieważ nie będzie działać przez cały czas i tylko doprowadzi do niespójności, będzie wyglądała źle i spowoduje więcej problemów. Myślę, że metody rozszerzenia są złe, ponieważ ukrywają fakt, że te metody nie są dynamicznie wywoływane. –

1

Niestety nie sądzę, że będziesz w stanie uzyskać to, czego chcesz. Metody rozszerzeń są statyczne, a metody statyczne nie mogą być wirtualne.

Można obejść to dzięki rozwiązaniu JaredPar.

Jeśli Twoim celem jest oddzielenie modelu od jakiejś implementacji, sugeruję, aby przyjrzeć się wzorowi mostu (GOF). "Oddziel abstrakcję od implementacji" Może to pomóc w oddzieleniu obaw i utrzymaniu klasy modelu w czystości.

Powiązane problemy