Dies kam mir in den Sinn, nachdem ich aus dieser Frage Folgendes gelernt hatte :
where T : struct
Wir, C # -Entwickler, kennen alle die Grundlagen von C #. Ich meine Deklarationen, Bedingungen, Schleifen, Operatoren usw.
Einige von uns beherrschten sogar die Dinge wie Generika , anonyme Typen , Lambdas , LINQ , ...
Aber was sind die verborgensten Funktionen oder Tricks von C #, die selbst C # -Fans, Süchtige und Experten kaum kennen?
Hier sind die bisher offenbarten Funktionen:
Schlüsselwörter
yield
von Michael Stumvar
von Michael Stumusing()
Aussage von Kokosreadonly
von kokosas
von Mike Stoneas
/is
von Ed Swangrenas
/is
(verbessert) von Rocketpantsdefault
von Deathofratsglobal::
von pzycomanusing()
Blöcke von AlexCusevolatile
von Jakub Šturcextern alias
von Jakub Šturc
Attribute
DefaultValueAttribute
von Michael StumObsoleteAttribute
von DannySmurfDebuggerDisplayAttribute
von StuDebuggerBrowsable
undDebuggerStepThrough
von bdukesThreadStaticAttribute
von MarxidadFlagsAttribute
von Martin ClarkeConditionalAttribute
von AndrewBurns
Syntax
??
(Koalesce Nulls) Operator von Kokos- Nummernschilder von Nick Berardi
where T:new
von Lars Mæhlum- Implizite Generika von Keith
- Ein-Parameter-Lambdas von Keith
- Auto-Eigenschaften von Keith
- Namespace-Aliase von Keith
- Wörtliche String-Literale mit @ von Patrick
enum
Werte von lfoust- @variablenames von marxidad
event
Betreiber von Marxidad- Formatieren Sie Zeichenfolgen in Klammern von Portman
- Eingabehilfen für den Zugriff auf Eigenschaften von xanadont
- Bedingter (ternärer) Operator (
?:
) von JasonS checked
undunchecked
Betreiber von Binoj Antonyimplicit and explicit
Betreiber von Flory
Sprachmerkmale
- Nullable Typen von Brad Barker
- Anonyme Typen von Keith
__makeref __reftype __refvalue
von Judah Himango- Objektinitialisierer von lomaxx
- Formatieren Sie Zeichenfolgen von David in Dakota
- Verlängerungsmethoden von Marxidad
partial
Methoden von Jon Erickson- Präprozessor-Direktiven von John Asbeck
DEBUG
Vorprozessor-Direktive von Robert Durgin- Überlastung des Bedieners durch SefBkn
- Typinferenz durch Chakrit
- Boolesche Operatoren von Rob Gough auf die nächste Stufe gebracht
- Übergeben Sie eine Variable vom Typ Wert als Schnittstelle ohne Boxen von Roman Boiko
- Programmgesteuerten deklarierten Variablentyp von Roman Boiko programmieren
- Statische Konstruktoren von Chris
- Einfacher auf den Augen / kondensierte ORM-Kartierung mit LINQ von Roosteronacid
__arglist
von Zac Bowling
Visual Studio-Funktionen
- Wählen Sie einen Textblock im Editor von Himadri
- Schnipsel von DannySmurf
Rahmen
TransactionScope
von KiwiBastardDependantTransaction
von KiwiBastardNullable<T>
von IainMHMutex
von DiagoSystem.IO.Path
von ageektrappedWeakReference
von Juan Manuel
Methoden und Eigenschaften
String.IsNullOrEmpty()
Methode von KiwiBastardList.ForEach()
Methode von KiwiBastardBeginInvoke()
,EndInvoke()
Methoden von Will DeanNullable<T>.HasValue
undNullable<T>.Value
Eigenschaften von RismoGetValueOrDefault
Methode von John Sheehan
Tipps
- Schöne Methode für Event-Handler von Andreas HR Nilsson
- Vergleiche in Großbuchstaben von John
- Zugriff auf anonyme Typen ohne Reflexion durch dp
- Ein schneller Weg, um Sammlungseigenschaften von Will träge zu instanziieren
- JavaScript-ähnliche anonyme Inline-Funktionen von Roosteronacid
Andere
- Netzmodule von Kokos
- LINQBridge von Duncan Smart
- Parallele Erweiterungen von Joel Coehoorn
quelle
"a".Equals("A", StringComparison.OrdinalIgnoreCase)
Mein Lieblingstrick ist die Verwendung des Null-Koaleszenz-Operators und der Klammern, um Sammlungen für mich automatisch zu instanziieren.
quelle
Vermeiden Sie es, nach Null-Ereignishandlern zu suchen
Das Hinzufügen eines leeren Delegaten zu Ereignissen bei der Deklaration und das Unterdrücken der Notwendigkeit, das Ereignis immer auf Null zu prüfen, bevor es aufgerufen wird, ist fantastisch. Beispiel:
Lass dich das machen
An Stelle von
Bitte beachten Sie auch diese verwandte Diskussion und diesen Blog-Beitrag von Eric Lippert zu diesem Thema (und möglichen Nachteilen).
quelle
Alles andere plus
1) implizite Generika (warum nur für Methoden und nicht für Klassen?)
2) einfache Lambdas mit einem Parameter:
3) anonyme Typen und Initialisierer:
Noch einer:
4) Auto-Eigenschaften können unterschiedliche Bereiche haben:
Danke @pzycoman, dass du mich daran erinnert hast:
5) Namespace-Aliase (nicht, dass Sie diese besondere Unterscheidung wahrscheinlich benötigen):
quelle
new web.Control()
würde auch in diesem Beispiel funktionieren. Die::
Syntax zwingt es, das Präfix als Namespace-Alias zu behandeln, sodass eine Klasse aufgerufen werden kannweb
und dieweb::Control
Syntax weiterhin funktioniert, während dieweb.Control
Syntax nicht weiß, ob die Klasse oder der Namespace überprüft werden soll. Aus diesem Grund verwende ich immer::
Namespace-Aliase.Ich kannte das Schlüsselwort "as" eine ganze Weile nicht.
vs.
Die zweite Option gibt null zurück, wenn obj keine MyClass ist, anstatt eine Klassenumwandlungsausnahme auszulösen.
quelle
Zwei Dinge, die mir gefallen, sind automatische Eigenschaften, mit denen Sie Ihren Code noch weiter reduzieren können:
wird
Auch Objektinitialisierer:
wird
quelle
[DefaultValue]
wird für den Designer verwendet, damit er weiß, ob eine Eigenschaft in Fettdruck angezeigt werden soll (dh nicht standardmäßig).Das 'Standard'-Schlüsselwort in generischen Typen:
führt zu 'null', wenn T ein Referenztyp ist, und 0, wenn es ein int ist, false, wenn es ein Boolescher Wert ist, usw.
quelle
Attribute im Allgemeinen, aber vor allem DebuggerDisplay . Spart dir Jahre.
quelle
Ich wollte dies nur klarstellen ... es sagt ihm nicht, dass er die Escape-Zeichen ignorieren soll, sondern dass der Compiler die Zeichenfolge als Literal interpretieren soll.
Wenn Sie haben
Es wird tatsächlich als gedruckt (beachten Sie, dass es sogar das zum Einrücken verwendete Leerzeichen enthält):
quelle
{{
auf{
und}}
zu}
macht es nützlich fürstring.Format()
.Ich denke, eine der am wenigsten geschätzten und weniger bekannten Funktionen von C # (.NET 3.5) sind Ausdrucksbäume , insbesondere in Kombination mit Generics und Lambdas. Dies ist ein Ansatz zur API-Erstellung, den neuere Bibliotheken wie NInject und Moq verwenden.
Angenommen, ich möchte eine Methode bei einer API registrieren und diese API muss den Methodennamen abrufen
Angesichts dieser Klasse:
Früher war es sehr üblich, dass Entwickler dies mit Zeichenfolgen und Typen (oder etwas anderem, das weitgehend auf Zeichenfolgen basiert) tun:
Nun, das ist scheiße wegen des Mangels an starker Typisierung. Was ist, wenn ich "SomeMethod" umbenenne? Jetzt, in Version 3.5, kann ich dies jedoch auf eine stark typisierte Weise tun:
In dem die RegisterMethod-Klasse Folgendes verwendet
Expression<Action<T>>
:Dies ist ein wichtiger Grund, warum ich gerade in Lambdas und Expression Trees verliebt bin.
quelle
EditValue(someEmployee, e => e.FirstName);
in meiner Geschäftslogik zu schreiben und automatisch die gesamte Installationslogik für ein ViewModel und eine View zu generieren, um diese Eigenschaft zu bearbeiten (also eine Beschriftung mit dem Text "Vorname" und eine TextBox mit eine Bindung, die den Setter der FirstName-Eigenschaft aufruft, wenn der Benutzer den Namen bearbeitet, und die Ansicht mit dem Getter aktualisiert). Dies scheint die Grundlage für die meisten neuen internen DSLs in C # zu sein." Ausbeute " würde mir in den Sinn kommen. Einige der Attribute wie [DefaultValue ()] gehören ebenfalls zu meinen Favoriten.
Das Schlüsselwort " var " ist etwas bekannter, aber dass Sie es auch in .NET 2.0-Anwendungen verwenden können (solange Sie den .NET 3.5-Compiler verwenden und ihn auf die Ausgabe von 2.0-Code einstellen), scheint nicht sehr bekannt zu sein Gut.
Edit: kokos, danke für den Hinweis auf die ?? Betreiber, das ist in der Tat sehr nützlich. Da es etwas schwierig ist, danach zu googeln (da ?? einfach ignoriert wird), finden Sie hier die MSDN-Dokumentationsseite für diesen Operator: ?? Operator (C # -Referenz)
quelle
Ich finde, dass die meisten C # -Entwickler nichts über 'nullable'-Typen wissen. Grundsätzlich Grundelemente, die einen Nullwert haben können.
Setzen Sie ein nullbares Double, num1 , auf null und setzen Sie dann ein reguläres Double, num2 , auf num1 oder -100, wenn num1 null war.
http://msdn.microsoft.com/en-us/library/1t3y8s4s(VS.80).aspx
eine weitere Sache über Nullable-Typ:
es ist return String.Empty. Überprüfen Sie diesen Link für weitere Details
quelle
as
Operatoren) allein mit Generika reproduzieren. Nullable <T> allein ist rudimentär und alles andere als herausragend, aber das Konzept der nullbaren Typen als Teil der Sprache ist umwerfend.Hier sind einige interessante versteckte C # -Funktionen in Form von undokumentierten C # -Schlüsselwörtern:
Dies sind undokumentierte C # -Schlüsselwörter (sogar Visual Studio erkennt sie!), Die für ein effizienteres Boxen / Unboxing vor Generika hinzugefügt wurden. Sie arbeiten in Abstimmung mit der System.TypedReference-Struktur.
Es gibt auch __arglist, die für Parameterlisten mit variabler Länge verwendet wird.
Eine Sache, über die die Leute nicht viel wissen, ist System.WeakReference - eine sehr nützliche Klasse, die ein Objekt verfolgt, es dem Garbage Collector jedoch ermöglicht, es zu sammeln.
Die nützlichste "versteckte" Funktion wäre das Schlüsselwort "return return". Es ist nicht wirklich versteckt, aber viele Leute wissen nichts darüber. Darauf baut LINQ auf; Es ermöglicht verzögert ausgeführte Abfragen, indem eine Zustandsmaschine unter der Haube erzeugt wird. Raymond Chen hat kürzlich über die internen Details berichtet .
quelle
Gewerkschaften (die C ++ Shared Memory-Art) in reinem, sicherem C #
Ohne auf unsicheren Modus und Zeiger zurückzugreifen, können Klassenmitglieder Speicherplatz in einer Klasse / Struktur gemeinsam nutzen. Gegeben die folgende Klasse:
Sie können die Werte der Bytefelder ändern, indem Sie das Int32-Feld bearbeiten und umgekehrt. Zum Beispiel dieses Programm:
Gibt dies aus:
Fügen Sie einfach mit System.Runtime.InteropServices hinzu.
quelle
Verwenden von @ für Variablennamen, bei denen es sich um Schlüsselwörter handelt.
quelle
Wenn Sie Ihr Programm beenden möchten, ohne endgültige Blöcke oder Finalizer aufzurufen , verwenden Sie FailFast :
quelle
Rückgabe anonymer Typen von einer Methode und Zugriff auf Mitglieder ohne Reflexion.
quelle
Hier ist eine nützliche für reguläre Ausdrücke und Dateipfade:
Das @ weist den Compiler an, alle Escape-Zeichen in einer Zeichenfolge zu ignorieren.
quelle
Mixins. Wenn Sie mehreren Klassen ein Feature hinzufügen möchten, aber nicht für alle eine Basisklasse verwenden können, muss jede Klasse eine Schnittstelle implementieren (ohne Mitglieder). Schreiben Sie dann eine Erweiterungsmethode für die Schnittstelle , dh
Natürlich wird etwas Klarheit geopfert. Aber es funktioniert!
quelle
Richtig , falsch, FileNotFound ?
quelle
Dieser ist nicht so sehr "versteckt", als dass er falsch benannt ist.
Viel Aufmerksamkeit wird den Algorithmen "Map", "Reduce" und "Filter" gewidmet. Was die meisten Leute nicht merken, ist, dass .NET 3.5 alle drei dieser Algorithmen hinzugefügt hat, aber es gab ihnen sehr SQL-ähnliche Namen, basierend auf der Tatsache, dass sie Teil von LINQ sind.
Die Möglichkeit, mit LINQ Inline-Arbeiten an Sammlungen durchzuführen, für die früher Iterationen und Bedingungen erforderlich waren, kann unglaublich wertvoll sein. Es lohnt sich zu lernen, wie alle LINQ-Erweiterungsmethoden dazu beitragen können, Ihren Code viel kompakter und wartbarer zu machen.
quelle
für systemunabhängige Zeilenumbrüche.
quelle
Wenn Sie versuchen, geschweifte Klammern in einem String.Format-Ausdruck zu verwenden ...
quelle
[
und]
sind eckige Klammern und<
und>
sind spitze Klammern. Siehe en.wikipedia.org/wiki/Bracket .quelle
@Ed, ich bin etwas zurückhaltend, wenn es darum geht, dies zu veröffentlichen, da es kaum mehr als ein Trottel ist. Ich möchte jedoch darauf hinweisen, dass in Ihrem Codebeispiel:
Wenn Sie 'is' verwenden möchten, warum sollten Sie dann eine sichere Besetzung mit 'as' durchführen? Wenn Sie festgestellt haben, dass es sich bei obj tatsächlich um MyClass handelt, eine Besetzung nach Moorstandard:
... wird niemals scheitern.
Ebenso könnte man einfach sagen:
Ich weiß nicht genug über die Innereien von .NET, um sicher zu sein, aber mein Instinkt sagt mir, dass dies maximal zwei Typ-Casts-Operationen auf maximal eine reduzieren würde. Es ist kaum wahrscheinlich, dass die Verarbeitungsbank so oder so kaputt geht. Ich persönlich denke, die letztere Form sieht auch sauberer aus.
quelle
is
und machtas
keine User Casts. Der obige Code fragt also denis
Operator, ob obj von MyClass abgeleitet ist (oder ob eine implizite systemdefinierte Umwandlung vorliegt). Auchis
nicht aufnull
. Diese beiden Randfälle können für Ihren Code wichtig sein. Zum Beispiel möchten Sie vielleicht schreiben:if( obj == null || obj is MyClass ) c = (MyClass)obj;
Dies unterscheidet sich jedoch stark von:try { c = (MyClass)obj; } catch { }
Da erstere keine benutzerdefinierten Konvertierungen durchführen, letztere jedoch. Ohne dienull
Prüfung wird erstere auch nicht gesetzt,c
wannobj
istnull
.IEnumerable<int>
toList<int>
und Castingobject
(new object()
) toIEnumerable<int>
, um sicherzustellen, dass es keine Fehler gibt: Direktcast: 5.43ns, is-> as cast: 6.75ns, as cast: 5.69ns. Testen Sie dann ungültige Casts: Direktcast: 3125000ns, als Cast: 5.41ns. Fazit: Machen Sie sich keine Gedanken mehr über den 1% -Faktor und stellen Sie sicher, dass Sie verwenden, wenn der Cast ungültig ist. Ausnahmen (auch wenn sie behandelt werden) sind im Vergleich zum Casting SEHR langsam. Wir sprechen von einem Faktor 578000, der langsamer ist. Denken Sie daran, dass der letzte Teil, der Rest spielt keine Rolle (.Net FW 4.0, Release Build)Vielleicht keine fortgeschrittene Technik, aber eine, die ich ständig sehe und die mich verrückt macht:
kann verdichtet werden zu:
quelle