Natknąłem się na kod, który powiedział
public int MaxHealth =>
Memory[Address].IsValid ?
Memory[Address].Read<int>(Offs.Life.MaxHp) :
0;
Teraz jestem nieco zaznajomiony z wyrażeniami Lambda. Po prostu nie widziałem, żeby używało go w ten sposób.
Jaka byłaby różnica między powyższym stwierdzeniem a
public int MaxHealth = x ? y:z;
Odpowiedzi:
To, na co patrzysz, to wyrazisty członek, a nie wyrażenie lambda.
Gdy kompilator napotka element właściwości wyrażony w wyrażeniu , zasadniczo konwertuje go do elementu pobierającego w następujący sposób:
(Możesz to sprawdzić samodzielnie, pompując kod do narzędzia o nazwie TryRoslyn ).
Członkowie o ekspresji - podobnie jak większość funkcji C # 6 - są po prostu cukrem syntaktycznym . Oznacza to, że nie zapewniają one funkcjonalności, której inaczej nie można byłoby uzyskać za pomocą istniejących funkcji. Zamiast tego te nowe funkcje umożliwiają stosowanie bardziej wyrazistej i zwięzłej składni
Jak widać, członkowie o wyrazistej budowie mają garść skrótów, dzięki którym członkowie właściwości są bardziej zwięzli:
return
instrukcji, ponieważ kompilator może wywnioskować, że chcesz zwrócić wynik wyrażeniaget
słowa kluczowego, ponieważ wynika to z użycia składni elementu wyrażenia.Pogrubiłem ostatni punkt, ponieważ dotyczy on twojego rzeczywistego pytania, na które odpowiem teraz.
Różnica pomiędzy...
I...
Jest taka sama jak różnica między ...
I...
Co - jeśli rozumiesz właściwości - powinno być oczywiste.
Jednak dla jasności: pierwszy wpis to właściwość z geterem pod maską, który będzie wywoływany za każdym razem, gdy do niego wejdziesz. Druga lista jest polem z inicjatorem pola, którego wyrażenie jest oceniane tylko raz, gdy tworzony jest typ.
Ta różnica w składni jest w rzeczywistości dość subtelna i może prowadzić do „gotcha”, którą opisuje Bill Wagner w poście zatytułowanym „AC # 6 gotcha: Initialization vs. Expression Bodied Members” .
Podczas gdy członkowie są treściwe wyrażenie lambda expression- jak są one nie wyrażenia lambda. Podstawowa różnica polega na tym, że wyrażenie lambda powoduje wystąpienie delegacji lub drzewa wyrażeń. Pełnoprawne wyrażenia są tylko kompilatorem kompilatora, który generuje właściwość za kulisami. Podobieństwo (mniej więcej) zaczyna się i kończy strzałką (
=>
).Dodam też, że członkowie o wyrazistym wyrazie nie są ograniczeni do członków własności. Pracują na wszystkich tych członkach:
Dodano w C # 7.0
Nie działają one jednak na tych członków:
źródło
Ok ... Skomentowałem, że były różne, ale nie potrafiłem dokładnie wyjaśnić, ale teraz wiem.
to nie to samo co
Oto różnica ...
Podczas korzystania z automatycznego inicjowania właściwość tworzy wystąpienie wartości i używa tej wartości w sposób trwały. W powyższym poście znajduje się uszkodzony link do Billa Wagnera, który dobrze to wyjaśnia, i sam szukałem odpowiedniego linku, aby go zrozumieć.
W mojej sytuacji kazałem mojej właściwości automatycznie zainicjować polecenie w ViewModel dla widoku. Zmieniłem właściwość, aby użyć inicjatora wyrażenia, a polecenie CanExecute przestało działać.
Oto jak to wyglądało i oto co się działo.
oto co zmieniłem na.
Różnica polega na tym, że kiedy używam
{ get; } =
, tworzę i odwołuję się do polecenia SAME w tej właściwości. Kiedy używam=>
, tworzę nowe polecenie i zwracam je przy każdym wywołaniu właściwości. Dlatego nigdy nie mogłem zaktualizowaćCanExecute
polecenia, ponieważ zawsze mówiłem, aby zaktualizowało nowe odwołanie do tego polecenia.Wszystko to powiedziało, jeśli tylko wskazujesz na pole zaplecza, to działa dobrze. Dzieje się tak tylko wtedy, gdy ciało auto lub wyrażenie tworzy wartość zwracaną.
źródło
Jest to nowa funkcja języka C # 6 o nazwie element wyrażający ciało, która pozwala zdefiniować właściwość tylko gettera za pomocą funkcji podobnej do lambda.
Chociaż uważa się go za cukier składniowy w następujących przypadkach, mogą one nie wytwarzać identycznej IL:
Okazuje się, że jeśli skompilujesz obie wersje powyższego i porównasz wygenerowaną IL dla każdej z nich, zobaczysz, że są one prawie takie same.
Oto IL dla klasycznej wersji w tej odpowiedzi, gdy zdefiniowano ją w klasie o nazwie
TestClass
:A oto IL dla wyrażonej w treści wersji członka, gdy jest zdefiniowany w klasie o nazwie
TestClass
:Zobacz https://msdn.microsoft.com/en-us/magazine/dn802602.aspx, aby uzyskać więcej informacji na temat tej i innych nowych funkcji w C # 6.
Zobacz ten post Różnica między właściwością a polem w C # 3.0+ na temat różnicy między polem a geterem właściwości w C #.
Aktualizacja:
Zauważ, że elementy o wyrazistej budowie zostały rozszerzone o właściwości, konstruktory, finalizatory i indeksatory w C # 7.0.
źródło
Nazywa się to Expression Bodied Member i został wprowadzony w C # 6. Jest to jedynie cukier składniowy nad
get
jedyną właściwością.Jest to równoważne z:
Dostępny jest odpowiednik deklaracji metody:
Głównie umożliwiając skrócenie płyty grzewczej.
źródło
Jeszcze jeden istotny punkt, jeśli używasz C # 6:
„=>” może być użyte zamiast „get” i dotyczy tylko metod „get only” - nie można go używać z „set”.
W przypadku C # 7 zobacz komentarz z @avenmore poniżej - można go teraz używać w większej liczbie miejsc. Oto dobre odniesienie - https://csharp.christiannagel.com/2017/01/25/expressionbodiedmembers/
źródło
Na poniższą wypowiedź udostępnioną przez Alexa Bookera w odpowiedzi
Zobacz poniższy zrzut ekranu , który pokazuje, w jaki sposób to oświadczenie (przy użyciu łącza SharpLab )
konwertuje na
Zrzut ekranu:
źródło