This came to my mind after I learned the following from this question:
where T : struct
We, C# developers, all know the basics of C#. I mean declarations, conditionals, loops, operators, etc.
Some of us even mastered the stuff like Generics, anonymous types, lambdas, LINQ, ...
But what are the most hidden features or tricks of C# that even C# fans, addicts, experts barely know?
Here are the revealed features so far:
Keywords
yield
by Michael Stumvar
by Michael Stumusing()
statement by kokosreadonly
by kokosas
by Mike Stoneas
/is
by Ed Swangrenas
/is
(improved) by Rocketpantsdefault
by deathofratsglobal::
by pzycomanusing()
blocks by AlexCusevolatile
by Jakub Šturcextern alias
by Jakub Šturc
Attributes
DefaultValueAttribute
by Michael StumObsoleteAttribute
by DannySmurfDebuggerDisplayAttribute
by StuDebuggerBrowsable
andDebuggerStepThrough
by bdukesThreadStaticAttribute
by marxidadFlagsAttribute
by Martin ClarkeConditionalAttribute
by AndrewBurns
Syntax
??
(coalesce nulls) operator by kokos- Number flaggings by Nick Berardi
where T:new
by Lars Mæhlum- Implicit generics by Keith
- One-parameter lambdas by Keith
- Auto properties by Keith
- Namespace aliases by Keith
- Verbatim string literals with @ by Patrick
enum
values by lfoust- @variablenames by marxidad
event
operators by marxidad- Format string brackets by Portman
- Property accessor accessibility modifiers by xanadont
- Conditional (ternary) operator (
?:
) by JasonS checked
andunchecked
operators by Binoj Antonyimplicit and explicit
operators by Flory
Language Features
- Nullable types by Brad Barker
- Anonymous types by Keith
__makeref __reftype __refvalue
by Judah Himango- Object initializers by lomaxx
- Format strings by David in Dakota
- Extension Methods by marxidad
partial
methods by Jon Erickson- Preprocessor directives by John Asbeck
DEBUG
pre-processor directive by Robert Durgin- Operator overloading by SefBkn
- Type inferrence by chakrit
- Boolean operators taken to next level by Rob Gough
- Pass value-type variable as interface without boxing by Roman Boiko
- Programmatically determine declared variable type by Roman Boiko
- Static Constructors by Chris
- Easier-on-the-eyes / condensed ORM-mapping using LINQ by roosteronacid
__arglist
by Zac Bowling
Visual Studio Features
- Select block of text in editor by Himadri
- Snippets by DannySmurf
Framework
TransactionScope
by KiwiBastardDependantTransaction
by KiwiBastardNullable<T>
by IainMHMutex
by DiagoSystem.IO.Path
by ageektrappedWeakReference
by Juan Manuel
Methods and Properties
String.IsNullOrEmpty()
method by KiwiBastardList.ForEach()
method by KiwiBastardBeginInvoke()
,EndInvoke()
methods by Will DeanNullable<T>.HasValue
andNullable<T>.Value
properties by RismoGetValueOrDefault
method by John Sheehan
Tips & Tricks
- Nice method for event handlers by Andreas H.R. Nilsson
- Uppercase comparisons by John
- Access anonymous types without reflection by dp
- A quick way to lazily instantiate collection properties by Will
- JavaScript-like anonymous inline-functions by roosteronacid
Other
- netmodules by kokos
- LINQBridge by Duncan Smart
- Parallel Extensions by Joel Coehoorn
@Ed, I'm a bit reticent about posting this as it's little more than nitpicking. However, I would point out that in your code sample:
If you're going to use 'is', why follow it up with a safe cast using 'as'? If you've ascertained that obj is indeed MyClass, a bog-standard cast:
...is never going to fail.
Similarly, you could just say:
I don't know enough about .NET's innards to be sure, but my instincts tell me that this would cut a maximum of two type casts operations down to a maximum of one. It's hardly likely to break the processing bank either way; personally, I think the latter form looks cleaner too.
Maybe not an advanced technique, but one I see all the time that drives me crazy:
can be condensed to:
This one is not "hidden" so much as it is misnamed.
A lot of attention is paid to the algorithms "map", "reduce", and "filter". What most people don't realize is that .NET 3.5 added all three of these algorithms, but it gave them very SQL-ish names, based on the fact that they're part of LINQ.
The ability to use LINQ to do inline work on collections that used to take iteration and conditionals can be incredibly valuable. It's worth learning how all the LINQ extension methods can help make your code much more compact and maintainable.
Attributes in general, but most of all DebuggerDisplay. Saves you years.
Everything else, plus
1) implicit generics (why only on methods and not on classes?)
2) simple lambdas with one parameter:
3) anonymous types and initialisers:
Another one:
4) Auto properties can have different scopes:
Thanks @pzycoman for reminding me:
5) Namespace aliases (not that you're likely to need this particular distinction):
Here are some interesting hidden C# features, in the form of undocumented C# keywords:
These are undocumented C# keywords (even Visual Studio recognizes them!) that were added to for a more efficient boxing/unboxing prior to generics. They work in coordination with the System.TypedReference struct.
There's also __arglist, which is used for variable length parameter lists.
One thing folks don't know much about is System.WeakReference -- a very useful class that keeps track of an object but still allows the garbage collector to collect it.
The most useful "hidden" feature would be the yield return keyword. It's not really hidden, but a lot of folks don't know about it. LINQ is built atop this; it allows for delay-executed queries by generating a state machine under the hood. Raymond Chen recently posted about the internal, gritty details.