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