Hidden Features of C#?

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 Stum
  • var by Michael Stum
  • using() statement by kokos
  • readonly by kokos
  • as by Mike Stone
  • as / is by Ed Swangren
  • as / is (improved) by Rocketpants
  • default by deathofrats
  • global:: by pzycoman
  • using() blocks by AlexCuse
  • volatile by Jakub Šturc
  • extern alias by Jakub Šturc
  • Attributes

  • DefaultValueAttribute by Michael Stum
  • ObsoleteAttribute by DannySmurf
  • DebuggerDisplayAttribute by Stu
  • DebuggerBrowsable and DebuggerStepThrough by bdukes
  • ThreadStaticAttribute by marxidad
  • FlagsAttribute by Martin Clarke
  • ConditionalAttribute 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 and unchecked operators by Binoj Antony
  • implicit 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 KiwiBastard
  • DependantTransaction by KiwiBastard
  • Nullable<T> by IainMH
  • Mutex by Diago
  • System.IO.Path by ageektrapped
  • WeakReference by Juan Manuel
  • Methods and Properties

  • String.IsNullOrEmpty() method by KiwiBastard
  • List.ForEach() method by KiwiBastard
  • BeginInvoke() , EndInvoke() methods by Will Dean
  • Nullable<T>.HasValue and Nullable<T>.Value properties by Rismo
  • GetValueOrDefault method by John Sheehan
  • Tips & Tricks

  • Nice method for event handlers by Andreas HR 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

  • This isn't C# per se, but I haven't seen anyone who really uses System.IO.Path.Combine() to the extent that they should. In fact, the whole Path class is really useful, but no one uses it!

    I'm willing to bet that every production app has the following code, even though it shouldn't:

    string path = dir + "" + fileName;
    

    lambdas and type inferrence are underrated. Lambdas can have multiple statements and they double as a compatible delegate object automatically (just make sure the signature match) as in:

    Console.CancelKeyPress +=
        (sender, e) => {
            Console.WriteLine("CTRL+C detected!n");
            e.Cancel = true;
        };
    

    Note that I don't have a new CancellationEventHandler nor do I have to specify types of sender and e , they're inferable from the event. Which is why this is less cumbersome to writing the whole delegate (blah blah) which also requires you to specify types of parameters.

    Lambdas don't need to return anything and type inference is extremely powerful in context like this.

    And BTW, you can always return Lambdas that make Lambdas in the functional programming sense. For example, here's a lambda that makes a lambda that handles a Button.Click event:

    Func<int, int, EventHandler> makeHandler =
        (dx, dy) => (sender, e) => {
            var btn = (Button) sender;
            btn.Top += dy;
            btn.Left += dx;
        };
    
    btnUp.Click += makeHandler(0, -1);
    btnDown.Click += makeHandler(0, 1);
    btnLeft.Click += makeHandler(-1, 0);
    btnRight.Click += makeHandler(1, 0);
    

    Note the chaining: (dx, dy) => (sender, e) =>

    Now that's why I'm happy to have taken the functional programming class :-)

    Other than the pointers in C, I think it's the other fundamental thing you should learn :-)


    From Rick Strahl:

    You can chain the ?? operator so that you can do a bunch of null comparisons.

    string result = value1 ?? value2 ?? value3 ?? String.Empty;
    
    链接地址: http://www.djcxy.com/p/1520.html

    上一篇: 你如何获得foreach循环的当前迭代的索引?

    下一篇: C#的隐藏特性?