2009-05-22 9 views
88

Były sytuacje, w których chciałbym zastąpić metodę w klasie metodą rozszerzającą. Czy jest jakiś sposób to zrobić w C#?Czy jest jakiś sposób w C#, aby zastąpić metodę klasy z metodą rozszerzenia?

Na przykład:

public static class StringExtension 
{ 
    public static int GetHashCode(this string inStr) 
    { 
     return MyHash(inStr); 
    } 
} 

Przypadek, w którym chciałem to zrobić, aby móc przechowywać hash ciąg do bazy danych i mają tę samą wartość być wykorzystywane przez wszystkich klas, które użyj skrótu klasy łańcuchowej (np. Słownik, itp.) Ponieważ wbudowany algorytm mieszania .Net nie może być kompatybilny z jedną wersją struktury do następnej, chcę ją zastąpić własną.

Jest jeszcze inny przypadek, w którym wpadłem tam, gdzie chciałbym zastąpić metodę klasy również metodą rozszerzającą, więc nie jest ona specyficzna tylko dla klasy ciągów lub metody GetHashCode.

Wiem, że mogłem to zrobić z podklasowaniem istniejącej klasy, ale byłoby to przydatne, aby móc to zrobić z rozszerzeniem w wielu przypadkach.

+0

Ponieważ słownik jest strukturą danych w pamięci , jaka to różnica, czy algorytm mieszający zmienia się z wersji frameworka na następną? Jeśli zmienia się wersja ramowa, to oczywiście aplikacja została zrestartowana, a słownik został ponownie zbudowany. –

Odpowiedz

83

Nie; metoda rozszerzenia nigdy nie ma pierwszeństwa przed metodą instancji z odpowiednią sygnaturą i nigdy nie bierze udziału w polimorfizmie (GetHashCode jest metodą virtual).

+0

"... nigdy nie bierze udziału w polimorfizmie (GetHashCode jest metodą wirtualną)" Czy mógłbyś wyjaśnić w inny sposób, dlaczego metoda rozszerzenia nigdy nie uczestniczyłaby w polimorfizmie, ponieważ jest wirtualna? Mam problemy z nawiązaniem połączenia z tymi dwoma stwierdzeniami. – Alex

+3

@Alex, mówiąc o wirtualnym, po prostu wyjaśniam, co to znaczy być polimorficznym. W praktycznie wszystkich zastosowaniach GetHashCode, konkretny typ jest nieznany - tak więc polimorfizm jest w grze. W związku z tym metody rozszerzenia nie pomogłyby **, nawet gdyby miały one priorytet ** w zwykłym kompilatorze. To, czego naprawdę chce OP, to łatanie małp. Które C# i .net nie ułatwiają. –

+3

To jest smutne, w C# tak wiele mylących metod niesensownych, jak np. '.ToString()' w tablicach. Jest to zdecydowanie potrzebna funkcja. –

6

Jeśli metoda ma inny podpis, można to zrobić - w twoim przypadku: nie.

Ale poza tym musisz użyć dziedziczenia, aby zrobić to, czego szukasz.

2

O ile mi wiadomo, odpowiedź brzmi: nie, ponieważ metoda rozszerzenia nie jest instancją. Bardziej przypomina to narzędzie intellisense, które pozwala wywołać metodę statyczną za pomocą instancji klasy. Myślę, że rozwiązaniem twojego problemu może być przechwytujący, który przechwytuje wykonanie określonej metody (np. GetHashCode()) i robi coś innego. Aby użyć takiego przechwytywacza (jak ten, który zapewnia Castle Project), wszystkie obiekty powinny być instansjonowane za pomocą fabryka obiektów (lub kontener IoC w zamku), aby ich interfejsy mogły być przechwytywane przez dynamiczny serwer proxy generowany w środowisku wykonawczym (Caslte pozwala również przechwytywać wirtualne elementy klas)

Powiązane problemy