1:確保集合的線程安全
如果使用.net4.0,有新的線程安全集合類
新的 System.Collections.Concurrent 命名空間引入了多個新的線程安全集合類,可在需要時隨時提供對項的無鎖訪問,並在鎖適用時提供細粒度鎖定。 在多線程方案中使用這些類應獲得優於集合類型(例如, ArrayList 和 List <(Of <(T >)>))的性能。
除了System.Collections.Concurrent空間下集合外,非泛型集合使用
lock(非泛型集合對象.SyncRoot)進行鎖定達到集合線程安全目的
泛型集合使用
static object sycObj = new object(); //是否static看具體應用
lock (sycObj)
{
//操作集合。
}
2:循環中先求長度還是使用list.Count,哪個效率高
第一類:
int len = list.Count;
for(int i; i<len; i++)
{
迭代
}
第二類:
for(int i; i<list.Count; i++)
{
迭代
}
答案是一樣高。
第一種方法完全沒有必要,很多人可能以為那樣會為代碼帶來效率,而實際上是不會給效率帶來任何提升。
因為事實上,索引器內部,為了安全期間,還是會去求整個list的count的。將兩者代碼貼出來可能會更好的理解這一點:
public T this[int index]
{
get
{
if (index >= this._size)
{
ThrowHelper.ThrowArgumentOutOfRangeException();
}
return this._items[index];
}
set
{
if (index >= this._size)
{
ThrowHelper.ThrowArgumentOutOfRangeException();
}
this._items[index] = value;
this._version++;
}
}
public int Count
{
get
{
return this._size;
}
}
3:善用延遲求值
以List<int> list = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};為例,說明linq查詢中的延遲求值和主動求值。
List<int> list = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var temp1 = from c in list where c > 5 select c;
var temp2 = (from c in list where c > 5 select c).ToList<int>();
list[0] = 11;
Console.Write("temp1: ");
foreach (var item in temp1)
{
Console.Write(item.ToString() + " ");
}
Console.Write("
temp2: ");
foreach (var item in temp2)
{
Console.Write(item.ToString() + " ");
}
4:謹慎泛型類型中的靜態成員
static void Main(string[] args)
{
MyList<int> list1 = new MyList<int>();
MyList<int> list2 = new MyList<int>();
MyList<string> list3 = new MyList<string>();
Console.WriteLine(MyList<int>.Count);
Console.WriteLine(MyList<string>.Count);
}
class MyList<T>
{
public static int Count { get; set; }
public MyList()
{
Count++;
}
}
代碼輸出是莫子?
只要知道 MyList<int> 和 MyList<string> 是兩個不同的類型,這題就不難理解了。.NET 中類型參數不同的封閉泛型類型是不同的類型。
5:小心閉包中的陷阱
for (int i = 0; i < 10; i++)
{
Action t = () =>
{
Console.WriteLine("t1:" + i.ToString());
};
t.BeginInvoke(null, null);
}
以上代碼的輸出為?
當閉包中引用了外部的局部變量或者方法參數的時候,C#會把該變量編譯成一個類的實例字段,頂樓的代碼編譯後實際上等效於:
TempClass tp = new TempClass();
for (tp.i = 0; tp.i < 10; tp.i++)
{
Action t = tp.TempMethod;
t.BeginInvoke(null, null);
}
TempClass是C#編譯器自動生成的類,其定義大概是這樣:
class TempClass
{
public int i;
public void TempMethod()
{
Console.Writeline("t1:" + i.ToString());
}
}
因為只循環10次,幾乎一瞬間就完了,因此第一個異步委托還沒開始執行 tp.i 就等於10了
6:event關鍵字的作用
既然使用委托也能實現回調,為什麼又需要event關鍵字。答曰:event 最大的作用就是防止在類的外部觸發類的事件。
7:區分IEnumerable<T>和IQueryable<T>
本地數據源用IEnumerable<T>,遠程數據源用IQueryable<T>。
針對LinqLINQ TO to OBJECTS,使用Enumerable中的擴展方法對本地集合進行排序、查詢等操作,查詢參數接受的是Func< >。Func< >叫做謂語表達式,相當於一個委托。針對LinqLINQ TO to SQL則使用Querable中的擴展方法,它接受的參數是Expression< >。Expression< >用於包裝Func< >。LinqLINQ TO to SQL引擎最終會將表達式樹轉化成為相應的SQL語句,然後在數據庫中執行。
8:選擇正確的集合
查看此文吧:html">http://www.BkJia.com/kf/201104/88261.html
9:泛型參數的約束是不是應該叫約定更好
在泛型的使用過程中,常常使用到的一個功能就是為泛型參數設定約束。約束聽上去像是限制了泛型參數的使用范圍,而實際上,約束本身確實拓展了泛型參數的使用。
一個沒有約束的泛型參數,只能具有object的行為和屬性,而一個指定約束為Student的泛型參數,卻可以使用類型Student的所有公開屬性和方法。
所以,俺覺得約束這個詞翻譯的實在不好,叫約定多好。
10:減少使用自定義委托
FCL中的3個(或者說3系列)委托已經滿足了大部分自定義委托的需求,所以基本上不再需要自定義委托了。
它們是:
Action表示接受0個或多個輸入參數,執行一段代碼,但是沒有任何返回值;
Func表示接受0個或多個輸入參數,執行一段代碼,同時有返回值;
Predicate表示定義一組條件並判斷參數是否符合條件;