[c#] C#的隱藏特性?



14 Answers

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中的指針,我認為這是你應該學習的另一個基本的東西:-)

Question

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

where T : struct

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

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

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

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


關鍵詞

屬性

句法

語言功能

Visual Studio功能

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

骨架

方法和屬性

提示與技巧

其他




一切,再加上

1)隱式泛型(為什麼只在方法上而不在類上)?

void GenericMethod<T>( T input ) { ... }

//Infer type, so
GenericMethod<int>(23); //You don't need the <>.
GenericMethod(23);      //Is enough.

2)帶一個參數的簡單lambda表達式:

x => x.ToString() //simplify so many calls

3)匿名類型和初始者:

//Duck-typed: works with any .Add method.
var colours = new Dictionary<string, string> {
    { "red", "#ff0000" },
    { "green", "#00ff00" },
    { "blue", "#0000ff" }
};

int[] arrayOfInt = { 1, 2, 3, 4, 5 };

另一個:

4)自動屬性可以有不同的範圍:

public int MyId { get; private set; }

感謝@pzycoman提醒我:

5)命名空間別名(不是你可能需要這種特殊的區別):

using web = System.Web.UI.WebControls;
using win = System.Windows.Forms;

web::Control aWebControl = new web::Control();
win::Control aFormControl = new win::Control();



我認為C#(.NET 3.5)中最受關注和鮮為人知的特性之一是表達式樹特別是當與泛型和Lambdas結合使用時。 這是API創建的一種方法,像NInject和Moq這樣的新型庫正在使用。

例如,假設我想用API註冊一個方法,並且該API需要獲取方法名稱

鑑於這個類:

public class MyClass
{
     public void SomeMethod() { /* Do Something */ }
}

之前,看到開發人員使用字符串和類型(或其他主要基於字符串的其他語言)來執行此操作非常常見:

RegisterMethod(typeof(MyClass), "SomeMethod");

那麼,由於缺乏強類型,這很糟糕。 如果我將“SomeMethod”重命名? 現在,在3.5中,我可以用強類型的方式來做到這一點:

RegisterMethod<MyClass>(cl => cl.SomeMethod());

其中RegisterMethod類使用Expression<Action<T>>如下所示:

void RegisterMethod<T>(Expression<Action<T>> action) where T : class
{
    var expression = (action.Body as MethodCallExpression);

    if (expression != null)
    {
        // TODO: Register method
        Console.WriteLine(expression.Method.Name);
    }
}

這是我現在愛上Lambdas和Expression Trees的一個重要原因。




純粹,安全的C#中的工會(C ++共享內存類)

不訴諸不安全的模式和指針,你可以讓類成員在類/結構體中共享內存空間。 鑑於以下課程:

[StructLayout(LayoutKind.Explicit)]
public class A
{
    [FieldOffset(0)]
    public byte One;

    [FieldOffset(1)]
    public byte Two;

    [FieldOffset(2)]
    public byte Three;

    [FieldOffset(3)]
    public byte Four;

    [FieldOffset(0)]
    public int Int32;
}

您可以通過操作Int32字段來修改字節字段的值,反之亦然。 例如,這個程序:

    static void Main(string[] args)
    {
        A a = new A { Int32 = int.MaxValue };

        Console.WriteLine(a.Int32);
        Console.WriteLine("{0:X} {1:X} {2:X} {3:X}", a.One, a.Two, a.Three, a.Four);

        a.Four = 0;
        a.Three = 0;
        Console.WriteLine(a.Int32);
    }

輸出這個:

2147483647
FF FF FF 7F
65535

只需使用System.Runtime.InteropServices添加;




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




Environment.NewLine

for system independent newlines.




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;



別名仿製藥:

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

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

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




  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



我傾向於發現大多數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鏈接了解更多詳情




我喜歡的兩件事是自動屬性,所以你可以進一步折疊你的代碼:

private string _name;
public string Name
{
    get
    {
        return _name;
    }
    set
    {
        _name = value;
    }
}

public string Name { get; set;}

還有對像初始化器:

Employee emp = new Employee();
emp.Name = "John Smith";
emp.StartDate = DateTime.Now();

Employee emp = new Employee {Name="John Smith", StartDate=DateTime.Now()}



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

True, False, FileNotFound ?




如果你想在不調用任何finally塊或finalizer的情況下退出你的程序,使用FailFast

Environment.FailFast()



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

private IList<Foo> _foo;

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



Here's a useful one for regular expressions and file paths:

"c:\\program files\\oldway"
@"c:\program file\newway"

The @ tells the compiler to ignore any escape characters in a string.




Related