Cela m'est venu à l'esprit après avoir appris ce qui suit à partir de cette question :
where T : struct
Nous, développeurs C #, connaissons tous les bases de C #. Je veux dire des déclarations, des conditions, des boucles, des opérateurs, etc.
Certains d'entre nous ont même maîtrisé des trucs comme les génériques , les types anonymes , les lambdas , LINQ , ...
Mais quelles sont les fonctionnalités ou astuces les plus cachées de C # que même les fans de C #, les toxicomanes, les experts connaissent à peine?
Voici les fonctionnalités révélées jusqu'à présent:
Mots clés
yield
par Michael Stumvar
par Michael Stumusing()
déclaration de kokosreadonly
par kokosas
par Mike Stoneas
/is
par Ed Swangrenas
/is
(amélioré) par Rocketpantsdefault
par deathofratsglobal::
par pzycomanusing()
blocs par AlexCusevolatile
par Jakub Šturcextern alias
par Jakub Šturc
Les attributs
DefaultValueAttribute
par Michael StumObsoleteAttribute
par DannySmurfDebuggerDisplayAttribute
par StuDebuggerBrowsable
etDebuggerStepThrough
par bdukesThreadStaticAttribute
par marxidadFlagsAttribute
par Martin ClarkeConditionalAttribute
par AndrewBurns
Syntaxe
??
(coalesce nulls ) opérateur par kokos- Signalisation numérique par Nick Berardi
where T:new
par Lars Mæhlum- Génériques implicites par Keith
- Lambdas à un paramètre par Keith
- Propriétés automatiques par Keith
- Alias d'espace de noms par Keith
- Verbatim string literals with @ by Patrick
enum
valeurs par lfoust- @variablenames par marxidad
event
opérateurs par marxidad- Format des parenthèses de chaîne par Portman
- Modificateurs d'accessibilité des accesseurs de propriété par xanadont
- Opérateur conditionnel (ternaire) (
?:
) par JasonS checked
etunchecked
opérateurs par Binoj Antonyimplicit and explicit
opérateurs par Flory
Caractéristiques linguistiques
- Types nullables par Brad Barker
- Types anonymes par Keith
__makeref __reftype __refvalue
par Judah Himango- Initialiseurs d'objets par lomaxx
- Format des chaînes de David dans le Dakota
- Méthodes d'extension par marxidad
partial
méthodes par Jon Erickson- Directives de préprocesseur par John Asbeck
DEBUG
directive pré-processeur par Robert Durgin- Surcharge de l'opérateur par SefBkn
- Inférence de type par chakrit
- Les opérateurs booléens poussés au niveau supérieur par Rob Gough
- Passer la variable de type valeur comme interface sans boxe par Roman Boiko
- Déterminer par programme le type de variable déclaré par Roman Boiko
- Constructeurs statiques par Chris
- Cartographie ORM plus facile à regarder / condensée à l'aide de LINQ par roosteronacid
__arglist
par Zac Bowling
Fonctionnalités de Visual Studio
- Sélectionnez un bloc de texte dans l'éditeur par Himadri
- Snippets par DannySmurf
Cadre
TransactionScope
par KiwiBastardDependantTransaction
par KiwiBastardNullable<T>
par IainMHMutex
par DiagoSystem.IO.Path
par ageektrappedWeakReference
par Juan Manuel
Méthodes et propriétés
String.IsNullOrEmpty()
méthode par KiwiBastardList.ForEach()
méthode par KiwiBastardBeginInvoke()
,EndInvoke()
méthodes de Will DeanNullable<T>.HasValue
etNullable<T>.Value
propriétés de RismoGetValueOrDefault
méthode par John Sheehan
Conseils & Astuces
- Belle méthode pour les gestionnaires d'événements par Andreas HR Nilsson
- Comparaisons majuscules par John
- Accéder aux types anonymes sans réflexion par dp
- Un moyen rapide d'instancier paresseusement les propriétés d'une collection par Will
- Fonctions en ligne anonymes de type JavaScript par roosteronacid
Autre
- netmodules par kokos
- LINQBridge par Duncan Smart
- Extensions parallèles par Joel Coehoorn
la source
"a".Equals("A", StringComparison.OrdinalIgnoreCase)
Mon astuce préférée consiste à utiliser l' opérateur de coalescence nulle et les parenthèses pour instancier automatiquement des collections pour moi.
la source
Évitez de rechercher les gestionnaires d'événements nuls
L'ajout d'un délégué vide aux événements lors de la déclaration, supprimant la nécessité de toujours vérifier l'événement pour null avant de l'appeler est génial. Exemple:
Laissez-vous faire
Au lieu de cela
Veuillez également consulter cette discussion connexe et cet article de blog d'Eric Lippert sur ce sujet (et les inconvénients possibles).
la source
Tout le reste, plus
1) génériques implicites (pourquoi uniquement sur les méthodes et non sur les classes?)
2) lambdas simples avec un paramètre:
3) types anonymes et initialiseurs:
Un autre:
4) Les propriétés automatiques peuvent avoir différentes portées:
Merci @pzycoman de m'avoir rappelé:
5) Alias d'espace de noms (pas que vous ayez probablement besoin de cette distinction particulière):
la source
new web.Control()
fonctionnerait également dans cet exemple. La::
syntaxe l'oblige à traiter le préfixe comme un alias d'espace de noms, donc vous pourriez avoir une classe appeléeweb
et laweb::Control
syntaxe fonctionnerait toujours, tandis que laweb.Control
syntaxe ne saurait pas s'il faut vérifier la classe ou l'espace de noms. Pour cette raison, j'ai tendance à toujours utiliser::
lors de la création d'alias d'espace de noms.Je ne connaissais pas le mot-clé "as" depuis un bon moment.
contre
La seconde retournera null si obj n'est pas une MyClass, plutôt que de lever une exception de transtypage de classe.
la source
Deux choses que j'aime sont les propriétés automatiques afin que vous puissiez réduire encore plus votre code:
devient
Aussi initialiseurs d'objets:
devient
la source
[DefaultValue]
est utilisé pour le concepteur afin qu'il sache s'il faut afficher une propriété en gras (ce qui signifie non par défaut).Le mot clé 'default' dans les types génériques:
résulte en un 'null' si T est un type de référence, et 0 s'il s'agit d'un int, false s'il s'agit d'un booléen, etc.
la source
Attributs en général, mais surtout DebuggerDisplay . Vous fait gagner des années.
la source
Je voulais juste clarifier celui-ci ... il ne lui dit pas d'ignorer les caractères d'échappement, il dit en fait au compilateur d'interpréter la chaîne comme un littéral.
Si tu as
il sera en fait imprimé comme (notez qu'il inclut même l'espace blanc utilisé pour l'indentation):
la source
{{
à{
et}}
à}
rendre utilestring.Format()
.Je pense que l'une des fonctionnalités les plus sous-estimées et moins connues de C # (.NET 3.5) sont les arbres d'expression , en particulier lorsqu'ils sont combinés avec des génériques et des Lambdas. Il s'agit d'une approche de la création d'API que les bibliothèques plus récentes comme NInject et Moq utilisent.
Par exemple, disons que je veux enregistrer une méthode avec une API et que l'API doit obtenir le nom de la méthode
Compte tenu de cette classe:
Avant, il était très courant de voir les développeurs faire cela avec des chaînes et des types (ou autre chose largement basé sur des chaînes):
Eh bien, ça craint à cause du manque de frappe forte. Et si je renomme "SomeMethod"? Maintenant, en 3.5 cependant, je peux le faire de manière fortement typée:
Dans lequel la classe RegisterMethod utilise
Expression<Action<T>>
comme ceci:C'est une grande raison pour laquelle je suis amoureux des Lambdas et des arbres d'expression en ce moment.
la source
EditValue(someEmployee, e => e.FirstName);
dans ma logique métier et le faire générer automatiquement toute la logique de plomberie pour un ViewModel et View pour modifier cette propriété (donc, une étiquette avec le texte "First Name" et une TextBox avec une liaison qui appelle le setter de la propriété FirstName lorsque l'utilisateur modifie le nom et met à jour la vue à l'aide du getter). Cela semble être la base de la plupart des nouvelles DSL internes en C #.« céder » me viendrait à l'esprit. Certains des attributs comme [DefaultValue ()] sont également parmi mes favoris.
Le mot-clé " var " est un peu plus connu, mais le fait que vous puissiez également l'utiliser dans les applications .NET 2.0 (tant que vous utilisez le compilateur .NET 3.5 et le définissez pour afficher le code 2.0) ne semble pas être très connu bien.
Edit: kokos, merci d'avoir souligné le ?? opérateur, c'est vraiment très utile. Comme il est un peu difficile de le rechercher sur Google (car ?? est simplement ignoré), voici la page de documentation MSDN pour cet opérateur: ?? Opérateur (référence C #)
la source
J'ai tendance à constater que la plupart des développeurs C # ne connaissent pas les types «nullables». Fondamentalement, des primitives qui peuvent avoir une valeur nulle.
Définissez un double nullable , num1 , sur null, puis définissez un double normal, num2 , sur num1 ou -100 si num1 était nul.
http://msdn.microsoft.com/en-us/library/1t3y8s4s(VS.80).aspx
encore une chose sur le type Nullable:
c'est return String.Empty. Consultez ce lien pour plus de détails
la source
as
opérateurs) avec des génériques seuls. Nullable <T> à lui seul est rudimentaire et loin d'être stellaire, mais le concept de types nullables dans le cadre du langage est kick ass.Voici quelques fonctionnalités C # cachées intéressantes, sous la forme de mots clés C # non documentés:
Ce sont des mots clés C # non documentés (même Visual Studio les reconnaît!) Qui ont été ajoutés pour une boxe / unboxing plus efficace avant les génériques. Ils travaillent en coordination avec la structure System.TypedReference.
Il y a aussi __arglist, qui est utilisé pour les listes de paramètres de longueur variable.
Les gens ne savent pas grand-chose sur System.WeakReference - une classe très utile qui garde la trace d'un objet mais permet toujours au garbage collector de le collecter.
La fonction "cachée" la plus utile serait le mot-clé return yield. Ce n'est pas vraiment caché, mais beaucoup de gens ne le savent pas. LINQ est construit au-dessus de cela; il permet des requêtes exécutées avec retard en générant une machine d'état sous le capot. Raymond Chen a récemment publié des détails sur les détails internes .
la source
Unions (du type mémoire partagée C ++) en C # pur et sûr
Sans recourir au mode et aux pointeurs non sécurisés, vous pouvez faire en sorte que les membres de la classe partagent l'espace mémoire dans une classe / structure. Étant donné la classe suivante:
Vous pouvez modifier les valeurs des champs d'octets en manipulant le champ Int32 et vice-versa. Par exemple, ce programme:
Produit ceci:
ajoutez simplement en utilisant System.Runtime.InteropServices;
la source
Utilisation de @ pour les noms de variables qui sont des mots clés.
la source
Si vous souhaitez quitter votre programme sans appeler de blocs ou de finaliseurs enfin, utilisez FailFast :
la source
Renvoyer des types anonymes à partir d'une méthode et accéder aux membres sans réflexion.
la source
En voici une utile pour les expressions régulières et les chemins de fichiers:
Le @ indique au compilateur d'ignorer tous les caractères d'échappement dans une chaîne.
la source
Mixins. Fondamentalement, si vous souhaitez ajouter une fonctionnalité à plusieurs classes, mais ne pouvez pas utiliser une classe de base pour toutes, demandez à chaque classe d'implémenter une interface (sans membres). Ensuite, écrivez une méthode d'extension pour l'interface , ie
Bien sûr, une certaine clarté est sacrifiée. Mais ça marche!
la source
Vrai, faux, FileNotFound ?
la source
Celui-ci n'est pas «caché» autant qu'il est mal nommé.
Une grande attention est accordée aux algorithmes "carte", "réduire" et "filtrer". Ce que la plupart des gens ne réalisent pas, c'est que .NET 3.5 a ajouté ces trois algorithmes, mais cela leur a donné des noms très SQL, basés sur le fait qu'ils font partie de LINQ.
La possibilité d'utiliser LINQ pour effectuer un travail en ligne sur des collections qui prenaient auparavant des itérations et des conditions peut être extrêmement utile. Il vaut la peine d'apprendre comment toutes les méthodes d'extension LINQ peuvent aider à rendre votre code beaucoup plus compact et maintenable.
la source
pour les sauts de ligne indépendants du système.
la source
Si vous essayez d'utiliser des accolades à l'intérieur d'une expression String.Format ...
la source
[
et]
sont des crochets et<
et>
sont des crochets. Voir en.wikipedia.org/wiki/Bracket .la source
@Ed, je suis un peu réticent à publier ceci, car c'est un peu plus que de taquiner. Cependant, je voudrais souligner que dans votre exemple de code:
Si vous allez utiliser «is», pourquoi le suivre avec un casting sûr en utilisant «as»? Si vous avez vérifié que obj est bien MyClass, un casting standard:
... ne va jamais échouer.
De même, vous pourriez simplement dire:
Je n'en sais pas assez sur les entrailles de .NET pour être sûr, mais mon instinct me dit que cela réduirait un maximum de deux opérations de conversion de type à un maximum. Il est peu probable de casser la banque de traitement de toute façon; personnellement, je pense que cette dernière forme semble plus propre aussi.
la source
is
etas
ne fera pas de cast utilisateur. Ainsi, le code ci-dessus demande à l'is
opérateur si obj est dérivé de MyClass (ou a une distribution définie implicitement par le système). , Égalementis
échoue surnull
. Ces deux cas marginaux peuvent être importants pour votre code. Par exemple, vous voudrez peut-être écrire:if( obj == null || obj is MyClass ) c = (MyClass)obj;
Mais ceci est strictement différent de:try { c = (MyClass)obj; } catch { }
puisque le premier n'effectuera aucune conversion définie par l'utilisateur, mais le second le fera. Sans lenull
contrôle, l'ancien sera pas non plus misc
enobj
estnull
.IEnumerable<int>
versList<int>
et en lançantobject
(new object()
) versIEnumerable<int>
, pour m'assurer qu'il n'y a pas d'erreurs: distribution directe: 5,43 ns, is-> en tant que distribution: 6,75 ns, en tant que distribution: 5,69 ns. Puis test des castes invalides: cast direct: 3125000ns, comme cast: 5.41ns. Conclusion: arrêtez de vous soucier du facteur 1%, et assurez-vous simplement que vous utilisez est / comme lorsque le cast peut être invalide, car les exceptions (également si elles sont gérées) sont TRÈS lentes par rapport au casting, nous parlons d'un facteur 578000 plus lent. Rappelez-vous que la dernière partie, le reste n'a pas d'importance (.Net FW 4.0, build build)Peut-être pas une technique avancée, mais celle que je vois tout le temps qui me rend fou:
peut être condensé en:
la source