Użycie słowa kluczowego „this” w parametrach formalnych dla metod statycznych w C #

286

Natknąłem się na kilka wystąpień kodu C #, takich jak:

public static int Foo(this MyClass arg)

W tym przypadku nie udało mi się znaleźć wyjaśnienia tego thissłowa kluczowego. Jakieś spostrzeżenia?

kpozin
źródło
10
Oprócz zaakceptowanej odpowiedzi, w przypadku metod rozszerzenia C # należy sprawdzić oficjalną dokumentację MSDN .
vulcan raven
4
Metody rozszerzeń są wygodne, ale musimy zachować ostrożność podczas ich tworzenia / używania - mogą się zepsuć! Cytat z ogólnych wytycznych w oficjalnej dokumentacji MSDN : „Ogólnie zalecamy stosowanie metod rozszerzenia oszczędnie i tylko wtedy, gdy jest to konieczne. ... Używając metody rozszerzenia do rozszerzenia typu, którego kodu źródłowego nie można zmienić, należy: ryzykować, że zmiana implementacji tego typu spowoduje uszkodzenie metody rozszerzenia. ”
Krishna Gupta
Czy to oznacza, że byłoby to możliwe? Bo tego właśnie szukam.
facepalm42

Odpowiedzi:

274

To jest metoda rozszerzenia . Zobacz tutaj wyjaśnienie .

Metody rozszerzeń pozwalają programistom dodawać nowe metody do zamówienia publicznego istniejącego typu CLR, bez konieczności dzielenia go na klasy lub ponownej kompilacji typu pierwotnego. Metody rozszerzeń pomagają łączyć elastyczność obsługi „typowania kaczego”, popularną obecnie w dynamicznych językach, z wydajnością i sprawdzaniem poprawności w przypadku języków silnie typowanych w czasie kompilacji.

Metody rozszerzeń umożliwiają szereg przydatnych scenariuszy i pomagają stworzyć naprawdę potężną strukturę zapytań LINQ ...

oznacza to, że możesz zadzwonić

MyClass myClass = new MyClass();
int i = myClass.Foo();

zamiast

MyClass myClass = new MyClass();
int i = Foo(myClass);

Pozwala to na budowę płynnych interfejsów, jak podano poniżej.

Preet Sangha
źródło
podklasa jest trudna
Gerry
@Gerry - co masz na myśli?
Preet Sangha
9
Przepraszam, mały sarkazm - w dzisiejszych czasach dużo składni wydaje się rozwiązywać problemy, o których nawet nie wiedziałem, że są problemami. Czytelność powinna mieć bardzo wysoki priorytet.
Gerry
2
Szczerze mówiąc @Gerry, brzmi to jakbyś był w klasycznym paradoksie Blub . Obecnie wiele składni rozwiązuje problemy, których nie masz, ponieważ nie wiedziałeś, że istnieje lepszy sposób lub nie wykonujesz zadań, dla których ta składnia jest świetna. Większość komentarzy na temat „ to rozwiązanie w poszukiwaniu problemu ” jest w rzeczywistości przykładem „ nie wiem, jak ta funkcja działa, więc musi być bezużyteczna ”.
Myrddin Emrys
53

Cytowany post na blogu Scott Gu ładnie to wyjaśnia.

Dla mnie odpowiedź na pytanie znajduje się w następującym stwierdzeniu w tym poście:

Zwróć uwagę, że powyższa metoda statyczna ma słowo kluczowe „this” przed argumentem pierwszego parametru typu string. Mówi to kompilatorowi, że tę konkretną metodę rozszerzenia należy dodać do obiektów typu „string”. W ramach implementacji metody IsValidEmailAddress () mogę następnie uzyskać dostęp do wszystkich publicznych właściwości / metod / zdarzeń faktycznego ciągu znaków, w którym metoda jest wywoływana, i zwracać wartość prawda / fałsz w zależności od tego, czy jest to poprawny adres e-mail, czy nie.

James Wiseman
źródło
9
To powinna być zaakceptowana odpowiedź. To jedyna odpowiedź, która faktycznie wyjaśnia, jaki jest rzeczywisty cel thissłowa kluczowego w podpisie metody. Inne odpowiedzi tylko nieprzydatnie mówią „to metoda rozszerzenia”. Nigdy w pełni nie rozumiałem, w jaki sposób metody rozszerzeń „przyczepiają się” do typów, które rozszerzają, aż do przeczytania tej odpowiedzi. Dziękuję Ci!
Lews Therin,
13

Oprócz objaśnienia Preet Sangha:
Intellisense wyświetla metody rozszerzenia za pomocą niebieskiej strzałki (np. Przed „Aggregate <>”):

wprowadź opis zdjęcia tutaj

Potrzebujesz

using the.namespace.of.the.static.class.with.the.extension.methods;

aby pojawiły się i były dostępne metody rozszerzenia, jeśli są w innej przestrzeni nazw niż kod, który ich używa.

Olivier Jacot-Descombes
źródło
4

Właśnie tego nauczyłem się innego dnia: to słowo kluczowe określa, że ​​metoda jest rozszerzeniem klasy, która ją kontynuuje. Na przykład, MyClass będzie miał nową metodę rozszerzenia o nazwie Foo (która nie akceptuje żadnego parametru i zwraca wartość int; może być używana jak w przypadku każdej innej metody publicznej).

jpoh
źródło
1

„this” rozszerza następną klasę na liście parametrów

Tak więc w podpisie metody poniżej „ten” rozszerza „Ciąg”. Linia jest przekazywana do funkcji jako normalny argument metody. publiczny ciąg statyczny [] SplitCsvLine (ta linia ciąg)

W powyższym przykładzie klasa „ta” rozszerza wbudowaną klasę „String”.

dcarl661
źródło