2011-08-23 11 views
7

Rozumiem, że metody rozszerzania C# muszą być statyczne. Czego nie rozumiem, dlaczego te rozszerzenia nie mogą być zdefiniowane w klasach niestatycznych lub ogólnych?Dlaczego w klasach statycznych należy zdefiniować metody rozszerzania C#?

Aktualizacja: Interesuje mnie przyczyna tej decyzji projektowej.

+0

Zanim zacznę zadawać to pytanie, szukam statycznego przypadku na klasę i nie znalazłem odpowiedzi, której dotyczy. Przy okazji nie jest to dokładnie to samo pytanie, a moja odpowiedź nie znajduje się w tym poście. – Mehran

+0

Jak to jest * dokładny * duplikat "Dlaczego nie można zadeklarować metod rozszerzenia w ogólnej klasie statycznej?". –

+0

To nie jest duplikat. Raczej bardziej szczegółowe pytanie z tak zwanego podwójnego. –

Odpowiedz

5

To więcej obserwacji niż odpowiedzi, ale ...

Kiedy wywołać metodę instancji, odniesienie do obiektu, do której dzwonisz jest umieszczana na stosie jako pierwszy argument w twojej wywołanie metody. Ten pierwszy argument to "to" i jest wykonywany niejawnie.

Po zdefiniowaniu metody rozszerzenia jawnie zdefiniuj "to" jako pierwszy argument.

Czy to możliwe, że rozdzielczość metody byłaby myląca, gdyby można było zdefiniować metody rozszerzeń metod instancji w tej samej klasie, tj. Zdefiniowanie metod o tej samej nazwie i, w rezultacie, tych samych parametrów, gdy "ten" parametr jest w zestawie.

+0

To wspaniała obserwacja i wiarygodna. Dziękuję za udostępnienie. – Mehran

+0

Być może, poza tym, że IMHO naprawdę powinien istnieć duży wyjątek od reguły: klasa lub struktura powinna mieć możliwość definiowania elementów rozszerzenia, które działają na elementach własnego typu, aw przypadku struktur, powinna istnieć możliwość "ten" parametr to albo wartość lub odniesienie. Takie metody rozszerzeń pozwoliłyby niezmiennym typom klas zachowywać się bardziej jak typy wartości w odniesieniu do inicjalizacji i umożliwiałyby stosowanie normalnej składni "metody" w mutatorach strukturalnych bez ryzyka, że ​​będą one stosowane w kontekstach tylko do odczytu. – supercat

+0

@supercat Jeśli mógłbyś zdefiniować metodę rozszerzenia w klasie, która działałaby sama, to nie byłaby to metoda rozszerzenia? –

1

Ponieważ specyfikacja mówi tak ... Teraz są prawdopodobnie dobre powody, dla których tak napisali specyfikację.

Powód, dla którego nie można ich zadeklarować w klasach ogólnych, jest dość oczywisty: biorąc pod uwagę sposób wywoływania metod rozszerzania, gdzie można określić argument typu dla klasy?

Powód, dla którego musi to być klasa statyczna, jest mniej oczywisty, ale myślę, że ma to sens. Głównym zastosowaniem klas statycznych jest grupowanie metod pomocniczych (np. Path, Directory, ProtectedData ...), a metody rozszerzeń są zasadniczo metodami pomocniczymi. Nie byłoby sensu, aby na przykład utworzyć instancję Enumerable lub Queryable.

+0

Rozumiem, co mówi spec. Chciałbym wiedzieć, dlaczego podejmowane są decyzje projektowe. – Mehran

+0

@Mehran, dokładnie to próbowałem wyjaśnić w mojej odpowiedzi ... Nie powtórzyłem tego, co mówi spec. –

+1

Metody rozszerzania publicznego byłyby znaczące tylko w klasie statycznej najwyższego poziomu, ale reguły mogłyby w rozsądny sposób umożliwić deklarację metod rozszerzenia w zagnieżdżonych klasach prywatnych lub chronionych, z zastrzeżeniem, że takie metody byłyby użyteczne tylko tam, gdzie jest to widoczne. Na przykład kod klasy "Foo " może skorzystać z możliwości zdefiniowania metody rozszerzenia, która używa typu, który jest prywatny dla 'Foo '. Taka metoda rozszerzenia nie miałaby problemu ze zrozumieniem, z jakiego 'T' należy korzystać, ponieważ jedyny kod, który mógłby to zobaczyć, miałby ten typ dostępny. – supercat

3

Spójrz do tego kawałka specyfikacji .NET C#:

Gdy pierwszy parametr metody zawiera modyfikator, że metoda nazywa się metodę rozszerzenia. Metody rozszerzeń można zadeklarować tylko w przypadku nie ogólnych, nie-zagnieżdżonych klas statycznych. Pierwszy parametr metody rozszerzającej może nie mieć żadnych modyfikatorów innych niż , a typ parametru nie może być typem wskaźnika.

A to fragment z Jon Skeet's answer:

To nie jest dla mnie jasne, dlaczego wszystkie te ograniczenia są konieczne - inny niż potencjalnie dla kompilatora języka specyfikacji (i) prostoty. I może zobaczyć, dlaczego sensowne jest ograniczanie go do typów nietypowych, ale I nie może od razu zobaczyć, dlaczego muszą być niezablokowane i statyczne. I podejrzewam, że reguły wyszukiwania są znacznie prostsze, jeśli nie musisz się martwić o typy zawarte w bieżącym typie itp., Ale ja śmiem twierdzić, że byłoby to możliwe.

Powiązane problemy