Czy C # ma właściwości rozszerzenia?
Na przykład, czy mogę dodać właściwość rozszerzenia do DateTimeFormatInfo
wywołanej, ShortDateLongTimeFormat
która zwróci ShortDatePattern + " " + LongTimePattern
?
c#
properties
extension-methods
Svish
źródło
źródło
?
enum
które mogą mieć właściwości i metody. C # 'senum
s nie może mieć właściwości lub metody, ale można utworzyć metody rozszerzenie na nich. To pytanie było dla mnie przydatne i nie powinno być zamknięte.Odpowiedzi:
W tej chwili kompilator Roslyn nie obsługuje go już po wyjęciu z pudełka ...
Do tej pory właściwości rozszerzenia nie były postrzegane jako wystarczająco wartościowe, aby można je było uwzględnić w poprzednich wersjach standardu C #. C # 7 i C # 8.0 postrzegają to jako mistrza propozycji, ale nie zostało jeszcze wydane, przede wszystkim dlatego, że nawet jeśli istnieje już implementacja, chcą to zrobić od samego początku.
Ale to będzie ...
Na liście prac w C # 7 znajduje się element rozszerzenia, więc może być obsługiwany w najbliższej przyszłości. Bieżący status właściwości rozszerzenia można znaleźć na Github w powiązanej pozycji .
Istnieje jednak jeszcze bardziej obiecujący temat, którym jest „rozszerzenie wszystkiego” ze szczególnym uwzględnieniem właściwości i klas statycznych, a nawet pól.
Ponadto możesz użyć obejścia
Jak określono w tym artykule , można użyć
TypeDescriptor
możliwości dołączenia atrybutu do instancji obiektu w czasie wykonywania. Jednak nie używa składni standardowych właściwości.Różni się nieco od cukru syntaktycznego, dodając możliwość zdefiniowania rozszerzonej właściwości, takiej
string Data(this MyClass instance)
jak alias metody rozszerzenia,string GetData(this MyClass instance)
ponieważ przechowuje dane w klasie.Mam nadzieję, że C # 7 zapewni w pełni funkcjonalne rozszerzenie wszystkiego (właściwości i pola), jednak w tym momencie tylko czas pokaże.
I nie krępuj się przyłączyć, ponieważ oprogramowanie jutra będzie pochodziło od społeczności.
Aktualizacja: sierpień 2016 r
Gdy zespół dotnet opublikował nowości w C # 7.0 oraz komentarz Madsa Torgensena :
Wygląda na to, że właściwości rozszerzenia i inni członkowie nadal są dobrymi kandydatami do włączenia w przyszłej wersji Roslyn, ale może nie w wersji 7.0.
Aktualizacja: maj 2017 r
Elementy rozszerzenia zostały zamknięte jako duplikat rozszerzenia wszystko, co również zostało zamknięte. Główna dyskusja dotyczyła w gruncie rzeczy rozszerzalności typu. Funkcja jest teraz śledzona tutaj jako propozycja i została usunięta z kamienia milowego 7.0 .
Aktualizacja: sierpień 2017 - proponowana funkcja C # 8.0
Chociaż nadal pozostaje tylko proponowaną funkcją, mamy teraz wyraźniejszy pogląd na jego składnię. Pamiętaj, że będzie to również nowa składnia metod rozszerzeń:
Podobne do klas częściowych, ale skompilowane jako osobna klasa / typ w innym zestawie. Uwaga: w ten sposób będziesz mógł dodawać statyczne elementy i operatory. Jak wspomniano w podcastie Madsa Torgensena , rozszerzenie nie będzie miało żadnego stanu (więc nie może dodawać prywatnych członków instancji do klasy), co oznacza, że nie będzie można dodawać danych prywatnych instancji powiązanych z instancją . Powodem jest to, że sugerowałoby to zarządzanie wewnętrznymi słownikami i może być trudne (zarządzanie pamięcią itp.). W tym celu możesz nadal korzystać z opisanej wcześniej techniki
TypeDescriptor
/ConditionalWeakTable
iz rozszerzeniem właściwości ukrywa ją pod ładną właściwością.Składnia nadal może ulec zmianie, ponieważ implikuje ten problem . Na przykład
extends
można je zastąpićfor
niektórymi, którzy mogą czuć się bardziej naturalni i mniej związani z javą.Aktualizacja grudzień 2018 r. - Role, rozszerzenia i statyczne elementy interfejsu
Rozszerzenie wszystko nie udało się do C # 8.0, z powodu niektórych wad wyjaśnionych jako koniec tego biletu GitHub . Przeprowadzono więc eksplorację w celu ulepszenia projektu. Tutaj Mads Torgensen wyjaśnia, jakie są role i rozszerzenia oraz czym się różnią:
Można to zaobserwować na podzieleniu poprzedniej propozycji w dwóch przypadkach użycia. Nowa składnia przedłużenie byłoby tak:
wtedy będziesz w stanie to zrobić:
A dla interfejsu statycznego :
Dodawanie właściwości Extension na
int
i traktowaćint
jakoIMonoid<int>
:źródło
Nie, nie istnieją w C # 3.0 i nie zostaną dodane w 4.0. Jest na liście potrzebnych funkcji dla C #, więc może zostać dodany w przyszłości.
W tym momencie najlepsze, co możesz zrobić, to metody rozszerzenia stylu GetXXX.
źródło
Nie, nie istnieją.
Wiem, że zespół C # rozważał je w pewnym momencie (a przynajmniej był to Eric Lippert) - wraz z konstruktorami i operatorami rozszerzeń (może to trochę potrwać, ale jesteś fajny ...) Jednak nie mam nie widziałem żadnych dowodów, że będą częścią C # 4.
EDYCJA: Nie pojawiły się w C # 5, a od lipca 2014 roku nie wygląda na to, że będzie w C # 6.
Eric Lippert , główny programista w zespole kompilatorów C # w firmie Microsoft do listopada 2012 r., Napisał o tym na blogu w październiku 2009 r .:
źródło
()
na końcu jest znacznie bardziej czytelne. Wiem dla mnie osobiście, co najmniej 90% rozszerzeń, które piszę, są z tych 2 typów.FullName
=FirstName + LastName
,ShortName
=FirstName + LastName[0]
. Chciałbym dodać więcej tych właściwości, ale nie chcę „brudzić” rzeczywistych klas. W tym przypadku właściwość rozszerzenia, która jest tylko do odczytu, jest idealna, ponieważ mogę dodać funkcjonalność, utrzymać klasę główną w czystości i nadal ujawniać informacje, które chcę ujawnić w interfejsie użytkownika.static implicit operator FileInfo(FileInfoEx fex)
który zwraca mój zawarty obiekt FileInfo. To skutecznie pozwala mi traktować FileInfoEx tak, jakby odziedziczył po FileInfo, nawet jeśli ta klasa jest zapieczętowana.Aktualizacja (dzięki @chaost za wskazanie tej aktualizacji):
Źródło: sekcja komentarzy w https://blogs.msdn.microsoft.com/dotnet/2018/11/12/building-c-8-0/
Przestałem liczyć, ile razy z biegiem lat otworzyłem to pytanie z nadzieją, że je zrealizuję.
W końcu wszyscy możemy się radować! Microsoft zamierza wprowadzić to w swojej nadchodzącej wersji C # 8.
Zamiast robić to ...
W końcu będziemy w stanie to zrobić tak ...
Źródło: https://blog.ndepend.com/c-8-0-features-glimpse-future/
źródło
Jak wspomniano @Psyonity, możesz użyć conditionalWeakTable, aby dodać właściwości do istniejących obiektów. W połączeniu z dynamicznym ExpandoObject można zaimplementować właściwości dynamicznego rozszerzenia w kilku wierszach:
Przykład użycia znajduje się w komentarzach xml:
źródło
Ponieważ ostatnio tego potrzebowałem, spojrzałem na źródło odpowiedzi w:
c # rozszerzyć klasę poprzez dodanie właściwości
i stworzył bardziej dynamiczną wersję:
Prawdopodobnie można go znacznie poprawić (nazewnictwo, dynamiczne zamiast łańcucha), obecnie używam tego w CF 3.5 wraz z hacky ConditionalWeakTable ( https://gist.github.com/Jan-WillemdeBruyn/db79dd6fdef7b9845e217958db98c4d4 )
źródło