C#的隱藏特性?




hidden-features (20)

@告訴編譯器忽略字符串中的任何轉義字符。

只是想澄清這一個......它沒有告訴它忽略轉義字符,它實際上告訴編譯器將字符串解釋為文字。

如果你有

string s = @"cat
             dog
             fish"

它將實際打印出來(注意它甚至包括用於縮進的空白):

cat
             dog
             fish

在我從這個問題中得知以下內容後,我想起了這件事

where T : struct

我們,C#開發人員,都知道C#的基礎知識。 我的意思是聲明,條件,循環,操作符等。

我們中有些人甚至掌握了Generics匿名類型lambdasLINQ等等。

但是C#中最隱藏的特性或技巧是什麼,甚至連C#粉絲,癮君子,專家都不知道?

以下是迄今為止顯示的功能:


關鍵詞

屬性

句法

語言功能

Visual Studio功能

  • Himadri編輯器中選擇文本塊
  • DannySmurf的片段

骨架

方法和屬性

提示與技巧

其他


Not sure why anyone would ever want to use Nullable<bool> though. :-)

True, False, FileNotFound ?


  1. ?? - coalescing operator
  2. using ( statement / directive ) - great keyword that can be used for more than just calling Dispose
  3. readonly - should be used more
  4. netmodules - too bad there's no support in Visual Studio

lambdas和類型推理被低估。 Lambdas可以有多個語句,並且它們自動加入兼容的委託對象 (只要確保簽名匹配),如下所示:

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

請注意,我沒有new CancellationEventHandler也不需要指定sendere類型,它們可以從事件中推導出來。 這就是為什麼編寫整個delegate (blah blah)不那麼麻煩,這也需要您指定參數類型。

Lambdas不需要返回任何東西 ,類型推斷在這種情況下非常強大。

順便說一下,你總是可以返回使Lambdas處於函數式編程意義上的Lambdas 。 例如,下面是一個使lambda處理Button.Click事件的lambda:

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);

注意鏈接: (dx, dy) => (sender, e) =>

這就是為什麼我很高興參加函數式編程課程:-)

除了C中的指針,我認為這是你應該學習的另一個基本的東西:-)


避免檢查空事件處理程序

在聲明中為事件添加一個空的委託,在調用它之前始終檢查事件是否為null是非常棒的。 例:

public delegate void MyClickHandler(object sender, string myValue);
public event MyClickHandler Click = delegate {}; // add empty delegate!

讓你這樣做

public void DoSomething()
{
    Click(this, "foo");
}

而不是這個

public void DoSomething()
{
    // Unnecessary!
    MyClickHandler click = Click;
    if (click != null) // Unnecessary! 
    {
        click(this, "foo");
    }
}

請參閱本文相關的討論和Eric Lippert撰寫的關於此主題的博客文章 (以及可能的缺點)。


@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:

MyClass c;
  if (obj is MyClass)
    c = obj as MyClass

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:

c = (MyClass)obj

...is never going to fail.

Similarly, you could just say:

MyClass c = obj as MyClass;
if(c != null)
{
   ...
}

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.


If you're trying to use curly brackets inside a String.Format expression...

int foo = 3;
string bar = "blind mice";
String.Format("{{I am in brackets!}} {0} {1}", foo, bar);
//Outputs "{I am in brackets!} 3 blind mice"

Maybe not an advanced technique, but one I see all the time that drives me crazy:

if (x == 1)
{
   x = 2;
}
else
{
   x = 3;
}

can be condensed to:

x = (x==1) ? 2 : 3;

Returning anonymous types from a method and accessing members without reflection.

// Useful? probably not.
private void foo()
{
    var user = AnonCast(GetUserTuple(), new { Name = default(string), Badges = default(int) });
    Console.WriteLine("Name: {0} Badges: {1}", user.Name, user.Badges);
}

object GetUserTuple()
{
    return new { Name = "dp", Badges = 5 };
}    

// Using the magic of Type Inference...
static T AnonCast<T>(object obj, T t)
{
   return (T) obj;
}

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.

"map" => Select
Transforms data from one form into another

"reduce" => Aggregate
Aggregates values into a single result

"filter" => Where
Filters data based on a criteria

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.


一般屬性,但最重要的是DebuggerDisplay 。 節省你的時間。


以下是一些有趣的隱藏C#特性,採用無證C#關鍵字的形式:

__makeref

__reftype

__refvalue

__arglist

這些都是未公開的C#關鍵字(甚至Visual Studio可以識別它們!),它們被添加到泛型之前的更高效的裝箱/拆箱。 它們與System.TypedReference結構協同工作。

還有__arglist,用於可變長度參數列表。

有一點人們不太了解的是System.WeakReference - 一個非常有用的類,它跟踪一個對象,但仍允許垃圾收集器收集它。

最有用的“隱藏”功能將是yield return關鍵字。 這並不是真的隱藏起來,但很多人都不知道。 LINQ建立在此之上; 它允許通過在引擎蓋下生成狀態機來執行延遲執行的查詢。 Raymond Chen最近發布了關於內部細節的詳細信息


來自Rick Strahl

你可以鏈接? 運算符,以便您可以執行一堆空比較。

string result = value1 ?? value2 ?? value3 ?? String.Empty;

別名仿製藥:

using ASimpleName = Dictionary<string, Dictionary<string, List<string>>>;

它允許你使用ASimpleName而不是Dictionary<string, Dictionary<string, List<string>>>

當你在很多地方使用相同的通用大型複雜事物時使用它。


我一段時間都不知道“as”關鍵字。

MyClass myObject = (MyClass) obj;

VS

MyClass myObject = obj as MyClass;

如果obj不是MyClass,則第二個將返回null,而不是拋出類轉換異常。


我傾向於發現大多數C#開發人員不知道“可空”類型。 基本上,可以有一個空值的原語。

double? num1 = null; 
double num2 = num1 ?? -100;

將一個可以為null的double num1設置為null,如果num1為null,則將常量 double num2設置為num1-100

http://msdn.microsoft.com/en-us/library/1t3y8s4s(VS.80).aspx

關於可空類型還有一件事:

DateTime? tmp = new DateTime();
tmp = null;
return tmp.ToString();

它返回String.Empty。 查看this鏈接了解更多詳情


我最喜歡的技巧是使用null coalesce操作符和括號來為我自動實例化集合。

private IList<Foo> _foo;

public IList<Foo> ListOfFoo 
    { get { return _foo ?? (_foo = new List<Foo>()); } }

我會想到“ yield ”。 一些像DefaultValueAttribute這樣的屬性也是我的最愛。

var ”關鍵字更為人所知,但您也可以在.NET 2.0應用程序中使用它(只要您使用.NET 3.5編譯器並將其設置為輸出2.0代碼)似乎並不十分清楚好。

編輯:kokos,謝謝你指出了?? 操作員,這確實非常有用。 由於它對Google來說有點難(因為??只是忽略了),下面是該運算符的MSDN文檔頁面: ?? ??


泛型類型中的'default'關鍵字:

T t = default(T);

如果T是引用類型,則返回'null';如果是int,則返回0;如果是boolean,則返回false。


這不是C#本身,但我沒有看到任何真正使用System.IO.Path.Combine()的人。 實際上,整個Path類非常有用,但沒有人使用它!

我敢打賭,每個生產應用程序都有以下代碼,即使它不應該:

string path = dir + "\\" + fileName;






hidden-features