對C#的瞭解是從大二開始做xml大作業時候開始的,當時我們的項目是使用asp.net實現,所以接觸到了c#,但接觸並不深入,都只是,像java、c++的使用一樣,簡單使用。到了大三才有比較系統的學習C#,也是因爲選了dotnet這門課,但也都是比較基礎的部分。
選了微軟實訓這門實訓方向課,學到了一些c#的高級使用方式,發現了C#編程好玩的地方。
首先,提到了泛型。
泛型是 2.0 版 C# 語言和公共語言運行庫 (CLR) 中的一個新功能。泛型將類型參數的概念引入 .NET Framework,類型參數使得設計如下類和方法成爲可能:這些類和方法將一個或多個類型的指定推遲到客戶端代碼聲明並實例化該類或方法的時候。例如,通過使用泛型類型參數 T,您可以編寫其他客戶端代碼能夠使用的單個類,而不致引入運行時強制轉換或裝箱操作的成本或風險。使用泛型類型可以最大限度地重用代碼、保護類型的安全以及提高性能。
泛型最常見的用途是創建集合類。您可以創建自己的泛型接口、泛型類、泛型方法、泛型事件和泛型委託。可以對泛型類進行約束以訪問特定數據類型的方法。
在我看來,泛型其實跟c++的模板很像。都是用一個<T>標識類型參數,在實例化時纔對類型賦值。這樣,就能很好的重用功能相同,但使用類型不同的代碼塊。而.NET中類庫新增的幾個泛型集合類就是吸收了以前非泛型集合類的優點,衍生出來的泛型集合類,這樣我們就可以根據自己的需求,爲自定義的類創建泛型接口或類等。
泛型的特點:
1、如果實例化泛型類型的參數相同,那麼JIT編譯器會重複使用該類型,因此C#的動態泛型能力避免了C++靜態模板可能導致的代碼膨脹的問題。
2 C#泛型類型攜帶有豐富的元數據,因此C#的泛型類型可以應用於強大的反射技術。
3、C#的泛型採用“基類,接口,構造器,值類型/引用類型”的約束方式來實現對類型能數的“顯式約束”,提高了類型安全的同時,也喪失了C++模板基於“簽名”的隱式約束所具有的高靈活性。
// type parameter T in angle brackets
public class GenericList<T>
{
// The nested class is also generic on T.
private class Node
{
// T used in non-generic constructor.
public Node(T t)
{
next = null;
data = t;
}
private Node next;
public Node Next
{
get { return next; }
set { next = value; }
}
// T as private member data type.
private T data;
// T as return type of property.
public T Data
{
get { return data; }
set { data = value; }
}
}
private Node head;
// constructor
public GenericList()
{
head = null;
}
// T as method parameter type:
public void AddHead(T t)
{
Node n = new Node(t);
n.Next = head;
head = n;
}
public IEnumerator<T> GetEnumerator()
{
Node current = head;
while (current != null)
{
yield return current.Data;
current = current.Next;
}
}
}
另外,在定義泛型類時,可以對客戶端代碼能夠在實例化類時用於類型參數的類型種類施加限制。如果客戶端代碼嘗試使用某個約束所不允許的類型來實例化類,則會產生編譯時錯誤。這些限制稱爲約束。約束是使用 where 上下文關鍵字指定的。
有六種約束類型:
T:結構 :類型參數必須是值類型。 可以指定除 Nullable 以外的任何值類型。 有關更多信息,請參見使用可以爲 null 的類型(C# 編程指南)。
T:類 :類型參數必須是引用類型;這一點也適用於任何類、接口、委託或數組類型。
T:new() :類型參數必須具有無參數的公共構造函數。 當與其他約束一起使用時,new() 約束必須最後指定。
T:<基類名> :類型參數必須是指定的基類或派生自指定的基類。
T:<接口名稱> :類型參數必須是指定的接口或實現指定的接口。 可以指定多個接口約束。 約束接口也可以是泛型的。
T:U :爲 T 提供的類型參數必須是爲 U 提供的參數或派生自爲 U 提供的參數。
public class Employee
{
private string name;
private int id;
public Employee(string s, int i)
{
name = s;
id = i;
}
public string Name
{
get { return name; }
set { name = value; }
}
public int ID
{
get { return id; }
set { id = value; }
}
}
public class GenericList<T> where T : Employee
{
private class Node
{
private Node next;
private T data;
public Node(T t)
{
next = null;
data = t;
}
public Node Next
{
get { return next; }
set { next = value; }
}
public T Data
{
get { return data; }
set { data = value; }
}
}
private Node head;
public GenericList() //constructor
{
head = null;
}
public void AddHead(T t)
{
Node n = new Node(t);
n.Next = head;
head = n;
}
public IEnumerator<T> GetEnumerator()
{
Node current = head;
while (current != null)
{
yield return current.Data;
current = current.Next;
}
}
public T FindFirstOccurrence(string s)
{
Node current = head;
T t = null;
while (current != null)
{
//The constraint enables access to the Name property.
if (current.Data.Name == s)
{
t = current.Data;
break;
}
else
{
current = current.Next;
}
}
return t;
}
}
然後,提到了Lambda 表達式
Lambda 表達式是一種可用於創建委託或表達式目錄樹類型的匿名函數。 通過使用 lambda 表達式,可以寫入可作爲參數傳遞或作爲函數調用值返回的本地函數。 Lambda 表達式對於編寫 LINQ 查詢表達式特別有用。若要創建 Lambda 表達式,需要在 Lambda 運算符 => 左側指定輸入參數,然後在另一側輸入表達式或語句塊。
(int x, string s) => s.Length > x//使用空括號指定零個輸入參數
() => SomeMethod()//沒有參數是使用()
普通綁定
public void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("ok");
}
this.button1.Click += button1_Click;
匿名委託
this.button1.Click += delegate(object sender, EventArgs e)
{
MessageBox.Show("Click");
};
表達式樹表示樹狀數據結構的代碼,樹狀結構中的每個節點都是一個表達式,例如一個方法調用或類似 x < y 的二元運算。
使用API創建表達式樹
// Add the following using directive to your code file:
// using System.Linq.Expressions;
// Create an expression tree.
Expression<Func<int, bool>> exprTree = num => num < 5;
// Decompose the expression tree.
ParameterExpression param = (ParameterExpression)exprTree.Parameters[0];
BinaryExpression operation = (BinaryExpression)exprTree.Body;
ParameterExpression left = (ParameterExpression)operation.Left;
ConstantExpression right = (ConstantExpression)operation.Right;
Console.WriteLine("Decomposed expression: {0} => {1} {2} {3}",
param.Name, left.Name, operation.NodeType, right.Value);
// This code produces the following output:
// Decomposed expression: num => num LessThan 5
最後就是LINQ,LINQ即語言集成查詢(Language Integrated Query)是一組用於c#和Visual Basic語言的擴展。它允許編寫C#或者Visual Basic代碼以查詢數據庫相同的方式操作內存數據。