32、總是優先考慮泛型
例如實現自己的List類
33、避免在泛型類型中聲明靜態成員
如果不想要不同類型共享相同是屬性,就別定義靜態成員
34、爲泛型參數設定約束
爲泛型添加約束後,可以使用約束相應的功能 例如new() 或者 :Person(某個自定義的類)
35、使用default爲泛型變量指定初始值
if()
{
return xx;
}else
{
return xx;
}
return default(T);
36、使用FCL中的委託聲明
使用Action Fun Predicate代替自定義的委託
37、使用Lambda表達式代替方法和匿名方法
Lambda本質就是匿名方法,但是寫起來更方便,看着整潔
38、小心閉包中的陷阱
List<Action> lists = new List<Action>();
for (int i = 0; i < 5; i++)
{
//int j = i;
Action a1 = () => Console.WriteLine(i);
lists.Add(a1);
}
foreach (Action item in lists)
{
item();
}
當我們使用匿名函數或Lambda並且要利用for循環裏面的索引值,同時此方法是在for循環之後調用的,那麼就會出現閉包問題
因爲() = > v "返回變量 v 的當前值",而不是創建該委託時"v“ 的返回值 。閉包”變量“,而不是閉包”值“。所以在”for“循環中的添加的匿名函數,只是返回了變量i 而不是i的值。所以知道f() 被真正執行時,i已經是values.Count 值啦,所以會拋出”超出索引範圍“。
C#是如何實現閉包的呢?
class Program
{
static void Main(string[] args)
{
List<Action> lists = new List<Action>();
TempClass tempClass = new TempClass();
for (tempClass.i = 0; tempClass.i < 5; tempClass.i++)
{
Action a1 = tempClass.TempFuc;
lists.Add(a1);
}
foreach (Action item in lists)
{
item();
}
}
}
class TempClass
{
public int i;
public void TempFuc()
{
Console.WriteLine(i.ToString());
}
}
編譯器會自動給我們創建一個類,在循環中每次會爲這個類的一個實例變量i賦值
按照下面這樣寫就會避免閉包
for (int i = 0; i < 5; i++)
{
int temp = i;
Action a1 = () => Console.WriteLine(temp);
lists.Add(a1);
}
上面的代碼和下面代碼其實是等效的
for (int i = 0; i < 5; i++)
{
TempClass tempClass = new TempClass();
tempClass.i = i;
Action a1 = tempClass.TempFuc;
lists.Add(a1);
}