重讀C#InDepth(一)
一本好書,或是一本比較有深度的書,就是每次研讀的時候都會有新的發現。
好吧,我承認每次讀的時候都有泛泛而過的嫌疑~~
這幾年一直專注於C#客戶端的開發,逐步從迷迷糊糊,到一知半解,再到自以為是,最後沉下心重新審視。也許這也是一種進步一種自我學習的過程。
前面啰嗦了這麼多,希望大家也能不那麼浮躁的“深入理解”C#這麼語言的每個知識點。本文總結書本中的知識,在結合實際應用場合進行概述,如果有不正確的地方,還請不吝指教。
文章中的內容比較淺顯,請高手略過此文。
1. 簡化了的COM操作
復制代碼
private void Button_Click(object sender, RoutedEventArgs e)
{
var Product = new List<Good>();
Product.Add(new Good() { Name = "Tom", Age = 21 });
Product.Add(new Good() { Name = "Json", Age = 22 });
Product.Add(new Good() { Name = "Jacob", Age = 26 });
var app = new Microsoft.Office.Interop.Excel.Application() { Visible = false };
Workbook wb = app.Workbooks.Add();
Worksheet ws = app.ActiveSheet;
int row = 1;
foreach (var good in Product)
{
ws.Cells[row, 1].Value = good.Name;
ws.Cells[row, 2].Value = good.Age; // Dynamic C# 4.0 syntax
row++;
}
wb.SaveAs(Filename: PractiseDemoLib.Util.RootPath + "Demo.xls", FileFormat: XlFileFormat.xlWorkbookNormal);
app.Application.Quit();
}
復制代碼
復制代碼
public class Good
{
public string Name { get; set; }
public Int32 Age { get; set; }
}
復制代碼
程序中引入Microsoft.Office.Interop.Excel組件,如果沒有可以下載,或者安裝Excel即可。
這是C#4.0 語法的優雅表達式(紅色字體部分),這樣避免了之前十分啰嗦的實現方式,Dynamic語法不僅僅局限在這裡,其在反射編程和與其他語音交互上有著“動態”的優勢,在之後的篇幅中會有介紹。
2. 泛型約束
復制代碼
public class A<T> where T : class ,IDisposable, new()
{
public string Name { get; set; }
}
public class A<T, U>
where T : class ,IDisposable, new()
where U : class,T
{
public string Name { get; set; }
}
/*
* 不能約束的例子
* Class B<T> : where T : Object, System.Enum, System.ValueType, System.Delegate
* * */
復制代碼
泛型的出現更多的是為了解決裝箱和拆箱的效率問題,並且利用泛型,程序得到更大程度的復用。而泛型約束就是約束輸入類型的類型,使其應該具有某類型的方法或屬性。
這裡有幾點要注意下:
1. 類型T可以約束成class,接口類型等,但不能約束成where T : Object, System.Enum, System.ValueType, System.Delegate。
2. 類型T的構造必須是無參構造函數(CLR並未有此約束,所以通過某些方式依然可以構建,只不過不是IDE模式下),即約束成new T() 模式,並且new() 要放在約束列表的最後。
3. 類型T可以被約束成類型U。
3. 靜態類型嵌套
涉及到靜態類型需要重點區分的是靜態類型和實例類型,靜態的構造和實例的構造。
復制代碼
public class Outer<T>
{
public class Inner<U, V>
{
readonly static int HashCode;
static bool IsInit = false;
static Inner()
{
HashCode = typeof(Outer<T>).GetHashCode();
}
public static void DynamicMethod(object sender)
{
var win = sender as MainWindow;
win.OutPutMsg(string.Format("[{4},{3}] Outer<{0}>.Inner<{1},{2}>", typeof(T), typeof(U), typeof(V), HashCode.ToString(), IsInit.ToString()));
IsInit = true;
}
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Outer<int>.Inner<string, DateTime>.DynamicMethod(this);
Outer<string>.Inner<int, int>.DynamicMethod(this);
Outer<object>.Inner<string, int>.DynamicMethod(this);
Outer<int>.Inner<string, DateTime>.DynamicMethod(this);
}
復制代碼
這個例子主要演示的是靜態構造函數只唯一初始化一回,這樣就導致了當點擊Button_Click之後,只會初始化三回對象,因為第一組和第四組,程序認為輸入參數都相同,只初始化一回靜態構造。
[False,29514189] Outer<System.Int32>.Inner<System.String,System.DateTime>
[False,53070131] Outer<System.String>.Inner<System.Int32,System.Int32>
[False,39345664] Outer<System.Object>.Inner<System.String,System.Int32>
[True,29514189] Outer<System.Int32>.Inner<System.String,System.DateTime>
上面就是顯示結果,大家可以對比下代碼。