To przyszło mi do głowy po tym, jak nauczyłem się z tego pytania :
where T : struct
My, programiści C #, wszyscy znamy podstawy C #. Mam na myśli deklaracje, warunki, pętle, operatory itp.
Niektórzy z nas opanowali nawet takie rzeczy, jak Generics , anonimowe typy , lambda , LINQ , ...
Ale jakie są najbardziej ukryte funkcje lub sztuczki C #, o których nawet fani C #, uzależnieni, eksperci ledwo wiedzą?
Oto dotychczas ujawnione funkcje:
Słowa kluczowe
yield
autor: Michael Stumvar
autor: Michael Stumusing()
wypowiedź kokosreadonly
autor: kokosas
autor: Mike Stoneas
/is
przez Ed Swangrenas
/is
(ulepszone) przez Rocketpantsdefault
przez deathofratsglobal::
przez pzycomanusing()
bloki przez AlexCusevolatile
autor: Jakub Šturcextern alias
autor: Jakub Šturc
Atrybuty
DefaultValueAttribute
autor: Michael StumObsoleteAttribute
autor: DannySmurfDebuggerDisplayAttribute
autor: StuDebuggerBrowsable
iDebuggerStepThrough
przez bdukesThreadStaticAttribute
przez marxidadFlagsAttribute
autor: Martin ClarkeConditionalAttribute
autor: AndrewBurns
Składnia
??
(koalesce nulls ) operator kokos- Oznaczenia liczbowe przez Nicka Berardi
where T:new
autor: Lars Mæhlum- Domniemane leki generyczne autorstwa Keitha
- Lambda jednoparametrowe Keitha
- Auto właściwości według Keitha
- Aliasy przestrzeni nazw autorstwa Keitha
- Dosłowne ciągi literałów z @ przez Patrick
enum
wartości według lfoust- @variablenames by marxidad
event
operatorzy przez marxidad- Sformatuj nawiasy ciągowe według Portmana
- Modyfikatory ułatwień dostępu przez Xanadont
- Operator warunkowy (trójskładnikowy) (
?:
) JasonS checked
orazunchecked
operatorzy Binoj Antonyimplicit and explicit
operatorzy Flory
Funkcje językowe
- Rodzaje zerowalne autorstwa Brada Barkera
- Anonimowe typy według Keitha
__makeref __reftype __refvalue
przez Judah Himango- Inicjalizatory obiektów przez lomaxx
- Formatuj ciągi znaków Davida w Dakocie
- Metody rozszerzenia autorstwa marxidad
partial
metody Jona Ericksona- Wytyczne preprocesora autorstwa Johna Asbecka
DEBUG
dyrektywa przedprocesorowa autorstwa Roberta Durgina- Przeciążenie operatora przez SefBkn
- Wpisz wnioskowanie według czakrytu
- Operatory logiczne przeniesione na wyższy poziom przez Roba Gougha
- Przekaż zmienną typu wartości jako interfejs bez boksu przez Romana Boiko
- Programowo określ deklarowany typ zmiennej przez Romana Boiko
- Static Constructors by Chris
- Łatwiejsze w użyciu / skondensowane mapowanie ORM za pomocą LINQ przez roosteronacid
__arglist
przez Zac Bowling
Funkcje programu Visual Studio
- Wybierz blok tekstu w edytorze autorstwa Himadri
- Fragmenty autorstwa DannySmurf
Struktura
TransactionScope
autor: KiwiBastardDependantTransaction
autor: KiwiBastardNullable<T>
przez IainMHMutex
przez DiagoSystem.IO.Path
przez ageektrappedWeakReference
autor: Juan Manuel
Metody i właściwości
String.IsNullOrEmpty()
metoda KiwiBastardList.ForEach()
metoda KiwiBastardBeginInvoke()
,EndInvoke()
metody Will DeanNullable<T>.HasValue
iNullable<T>.Value
właściwości RismoGetValueOrDefault
metoda Johna Sheehana
Porady & Triki
- Fajna metoda dla organizatorów wydarzeń autorstwa Andreasa HR Nilssona
- Porównania wielkich liter Johna
- Dostęp do typów anonimowych bez refleksji przez dp
- Szybki sposób na leniwe tworzenie instancji właściwości kolekcji przez Willa
- JavaScript-anonimowe funkcje wstawiane przez roosteronacid
Inny
- netmodules od kokos
- LINQBridge firmy Duncan Smart
- Rozszerzenia równoległe autorstwa Joela Coehoorna
źródło
"a".Equals("A", StringComparison.OrdinalIgnoreCase)
Moją ulubioną sztuczką jest użycie operatora koalescencji zerowej i nawiasów do automatycznego tworzenia instancji kolekcji.
źródło
Unikaj sprawdzania procedur obsługi zdarzeń o wartości NULL
Dodanie pustego delegata do zdarzeń w momencie deklaracji, eliminując potrzebę sprawdzania zdarzenia pod kątem wartości zerowej przed wywołaniem, jest niesamowite. Przykład:
Pozwól to zrobić
Zamiast tego
Zobacz także pokrewną dyskusję i ten post na blogu Erica Lipperta na ten temat (i możliwe wady).
źródło
Wszystko inne plus
1) niejawne leki generyczne (dlaczego tylko na metodach, a nie na klasach?)
2) proste lambdy z jednym parametrem:
3) anonimowe typy i inicjatory:
Inny:
4) Właściwości automatyczne mogą mieć różne zakresy:
Dzięki @pzycoman za przypomnienie:
5) Aliasy przestrzeni nazw (nie dlatego, że prawdopodobnie będziesz potrzebować tego konkretnego rozróżnienia):
źródło
new web.Control()
również działałby w tym przykładzie. W::
Zmusza składniowe traktować jako alias prefiks przestrzeni nazw, więc można mieć klasę o nazwieweb
iweb::Control
składnia będzie nadal działać, aweb.Control
składnia nie wiem czy by sprawdzić klasę lub nazw. Z tego powodu zwykle używam::
przy tworzeniu aliasów przestrzeni nazw.Od dłuższego czasu nie znałem słowa kluczowego „jako”.
vs
Drugi zwróci null, jeśli obj nie jest MyClass, zamiast zgłosić wyjątek rzutowania na klasę.
źródło
Dwie rzeczy, które lubię, to właściwości automatyczne, dzięki czemu możesz jeszcze bardziej zwinąć kod:
staje się
Również obiekty inicjujące:
staje się
źródło
[DefaultValue]
służy projektantowi, więc wie, czy wyświetlać pogrubioną właściwość (co oznacza, że nie jest domyślna).„Domyślne” słowo kluczowe w typach ogólnych:
skutkuje wartością „null”, jeśli T jest typem odniesienia, a 0, jeśli jest liczbą całkowitą, false, jeśli jest wartością logiczną itp.
źródło
Atrybuty ogólnie, ale przede wszystkim DebuggerDisplay . Oszczędza ci lat.
źródło
Chciałem tylko wyjaśnić ten ... nie mówi, aby ignorował znaki specjalne, w rzeczywistości mówi kompilatorowi, aby interpretował ciąg jako literał.
Jeśli masz
faktycznie wydrukuje jako (zwróć uwagę, że zawiera nawet spację używaną do wcięcia):
źródło
{{
do{
i}}
na}
co przydatne dlastring.Format()
.Myślę, że jedną z najbardziej niedocenianych i mniej znanych funkcji C # (.NET 3.5) są drzewa wyrażeń , szczególnie w połączeniu z Generics i Lambdas. Jest to podejście do tworzenia API, z którego korzystają nowsze biblioteki, takie jak NInject i Moq.
Powiedzmy na przykład, że chcę zarejestrować metodę za pomocą interfejsu API i że interfejs API musi uzyskać nazwę metody
Biorąc pod uwagę tę klasę:
Wcześniej bardzo często obserwowano, jak programiści robią to z łańcuchami i typami (lub czymś innym, w dużej mierze opartym na łańcuchach):
Cóż, to do bani z powodu braku silnego pisania. Co się stanie, jeśli zmienię nazwę „SomeMethod”? Teraz, w wersji 3.5, mogę to zrobić w mocno typowy sposób:
W którym klasa RegisterMethod używa w
Expression<Action<T>>
ten sposób:Jest to jeden z głównych powodów, dla których jestem teraz zakochany w Lambdas i drzewkach ekspresyjnych.
źródło
EditValue(someEmployee, e => e.FirstName);
w mojej logice biznesowej i automatycznie wygenerowałem całą logikę hydrauliczną dla ViewModel i View do edycji tej właściwości (więc etykieta z tekstem „First Name” i TextBox z powiązanie, które wywołuje funkcję ustawiającą właściwość FirstName, gdy użytkownik edytuje nazwę i aktualizuje widok za pomocą modułu pobierającego). Wydaje się, że jest to podstawa dla większości nowych wewnętrznych DSL w C #.przychodzi mi na myśl „ dochód ”. Niektóre atrybuty, takie jak [DefaultValue ()], również należą do moich ulubionych.
Słowo kluczowe „ var ” jest nieco bardziej znane, ale można go również używać w aplikacjach .NET 2.0 (o ile używasz kompilatora .NET 3.5 i ustawiasz go na kod wyjściowy 2.0), wydaje się, że nie jest bardzo znany dobrze.
Edycja: kokos, dzięki za wskazanie ?? operator, to naprawdę bardzo przydatne. Ponieważ wyszukiwanie google jest trochę trudne (ponieważ ?? jest po prostu ignorowane), oto strona dokumentacji MSDN tego operatora: ?? Operator (C # Reference)
źródło
Zwykle stwierdzam, że większość programistów C # nie wie o typach „zerowalnych”. Zasadniczo prymitywy, które mogą mieć wartość zerową.
Ustaw nullable double, num1 , na null, a następnie ustaw zwykłe double, num2 , na num1 lub -100, jeśli num1 było null.
http://msdn.microsoft.com/en-us/library/1t3y8s4s(VS.80).aspx
jeszcze jedna rzecz o typie Nullable:
zwracany jest String.Empty. Sprawdź ten link, aby uzyskać więcej informacji
źródło
as
operatorami) tylko z danymi ogólnymi. Nullable <T> sam jest szczątkowy i daleki od gwiezdnego, ale pojęcie typów nullable jako części języka to kick ass.Oto kilka interesujących ukrytych funkcji C #, w postaci nieudokumentowanych słów kluczowych C #:
Są to nieudokumentowane słowa kluczowe C # (nawet Visual Studio je rozpoznaje!), Które zostały dodane do bardziej efektywnego boksowania / rozpakowywania przed generycznymi. Działają w koordynacji z strukturą System.TypedReference.
Istnieje również __arglist, który jest używany do list parametrów o zmiennej długości.
Jedną z rzeczy, o których ludzie nie wiedzą zbyt wiele, jest System.WeakReference - bardzo przydatna klasa, która śledzi obiekt, ale nadal pozwala zbieraczowi śmieci go gromadzić.
Najbardziej użyteczną funkcją „ukrytą” byłoby słowo kluczowe zwrotu z zysku. Nie jest tak naprawdę ukryty, ale wielu ludzi nie wie o tym. LINQ jest zbudowany na szczycie; pozwala na zapytania wykonywane z opóźnieniem, generując maszynę stanu pod maską. Raymond Chen niedawno napisał o wewnętrznych, szorstkich szczegółach .
źródło
Związki (rodzaj pamięci współużytkowanej w C ++) w czystym, bezpiecznym języku C #
Bez uciekania się do niebezpiecznego trybu i wskaźników, członkowie klasy mogą dzielić przestrzeń pamięci w klasie / strukturze. Biorąc pod uwagę następującą klasę:
Możesz modyfikować wartości pól bajtów, manipulując polem Int32 i odwrotnie. Na przykład ten program:
Wyprowadza to:
wystarczy dodać za pomocą System.Runtime.InteropServices;
źródło
Użycie @ dla nazw zmiennych, które są słowami kluczowymi.
źródło
Jeśli chcesz wyjść z programu bez wywoływania bloków lub finalizatorów, użyj funkcji FailFast :
źródło
Zwracanie anonimowych typów z metody i uzyskiwanie dostępu do członków bez refleksji.
źródło
Oto przydatne dla wyrażeń regularnych i ścieżek plików:
@ Mówi kompilatorowi, aby zignorował wszelkie znaki specjalne w ciągu.
źródło
Mixiny Zasadniczo, jeśli chcesz dodać funkcję do kilku klas, ale nie możesz użyć jednej klasy bazowej dla wszystkich z nich, poproś każdą klasę o wdrożenie interfejsu (bez członków). Następnie napisz metodę rozszerzenia interfejsu , tj
Oczywiście poświęcono trochę jasności. Ale to działa!
źródło
Prawda, fałsz, FileNotFound ?
źródło
Ten nie jest „ukryty”, ale jest źle nazwany.
Wiele uwagi poświęca się algorytmom „mapuj”, „zmniejszaj” i „filtruj”. Większość ludzi nie zdaje sobie sprawy, że .NET 3.5 dodał wszystkie trzy z tych algorytmów, ale nadał im bardzo SQL-owe nazwy, w oparciu o fakt, że są częścią LINQ.
Możliwość korzystania z LINQ do wykonywania prac inline na kolekcjach, które były używane do iteracji i operacji warunkowych, może być niezwykle cenna. Warto dowiedzieć się, w jaki sposób wszystkie metody rozszerzenia LINQ mogą pomóc w zwiększeniu kompaktowości i łatwości obsługi kodu.
źródło
dla niezależnych od systemu nowych linii.
źródło
Jeśli próbujesz użyć nawiasów klamrowych w wyrażeniu String.Format ...
źródło
[
i]
są nawiasami kwadratowymi,<
i>
są nawiasami kątowymi. Zobacz en.wikipedia.org/wiki/Bracket .źródło
@Ed, jestem trochę niechętny publikowaniu tego, ponieważ jest to coś więcej niż nitpicking. Chciałbym jednak zauważyć, że w twoim kodzie przykładowym:
Jeśli masz zamiar użyć „jest”, po co po bezpiecznej obsadzie, używając „jako”? Jeśli upewniłeś się, że obj to rzeczywiście MyClass, obsada standardowa:
... nigdy nie zawiedzie.
Podobnie możesz po prostu powiedzieć:
Nie mam wystarczającej wiedzy o wewnętrznych dodatkach .NET, aby się upewnić, ale instynkt podpowiada mi, że ograniczyłoby to maksymalnie dwie operacje rzutowania typu do maksymalnie jednej. Jest mało prawdopodobne, że tak czy inaczej złamie bank przetwarzania; osobiście uważam, że ta druga forma też wygląda na czystszą.
źródło
is
ias
nie będzie wykonywać rzutowań użytkowników. Tak więc powyższy kod pytais
operatora, czy obiekt obcy pochodzi z MyClass (czy ma niejawną obsadę zdefiniowaną przez system). Ponadtois
zawiesza sięnull
. Oba te przypadki krawędzi mogą być ważne dla twojego kodu. Na przykład możesz chcieć napisać:if( obj == null || obj is MyClass ) c = (MyClass)obj;
Ale jest to zupełnie inne niż:try { c = (MyClass)obj; } catch { }
ponieważ ten pierwszy nie wykona żadnych konwersji zdefiniowanych przez użytkownika, ale drugi zrobi to. Bez tejnull
opcji pierwsza nie ustawi się również,c
kiedyobj
jestnull
.IEnumerable<int>
doList<int>
i castingobject
(new object()
) doIEnumerable<int>
, aby upewnić się, że nie ma błędów: rzutowanie bezpośrednie: 5,43ns, is-> as cast: 6,75ns, as cast: 5,69ns. Następnie testowanie nieprawidłowych rzutowań: rzutowanie bezpośrednie: 3125000ns, jako rzutowanie: 5.41ns. Wniosek: przestań się martwić współczynnikiem 1% i po prostu upewnij się, że używasz / jest, gdy rzutowanie może być nieprawidłowe, ponieważ wyjątki (także jeśli są obsługiwane) są BARDZO powolne w porównaniu do przesyłania, mówimy o współczynniku 578000 wolniejszym. Pamiętaj, że ostatnia część, reszta nie ma znaczenia (.Net FW 4.0, wydanie kompilacji)Może nie jest to zaawansowana technika, ale taka, którą cały czas widzę, doprowadza mnie do szału:
może być skondensowany do:
źródło