1. 匿名型別
通過關鍵字var定義匿名型別,編譯器將根據運算子右側表示式的值來發出一個強型別。
使用匿名型別時要遵守的一些基本規則:
◊ 匿名型別必須有一個初始化值,而且這個值不能是空值(null),因為型別是根據初始化器推斷出來的;
◊ 匿名型別可以用於簡單型別,也可以用於複雜型別。用於定義簡單型別時,其價值不大。複合匿名型別需要有成員宣告;
◊ 匿名型別不能用於類的欄位;
◊ 匿名型別可以在for迴圈中用作初始化器;
◊ 可以使用new關鍵字;陣列的初始化器必須使用new關鍵字;
◊ 匿名型別可以用於陣列;
◊ 所有匿名型別都派生自Object型別;
var title = "LINQ to Object";
1.1 複合匿名型別
var product = new { Title = "LINQ to Object", UnitPrice = 10m };
1.2 在for/foreach語句中使用匿名型別
var fibonacci = new int[] { 1, 1, 2, 3, 5, 8, 13, 21 }; for (var i = 0; i < fibonacci.Length; i++) { Console.WriteLine(fibonacci[i]); }
var fibonacci = new int[] { 1, 1, 2, 3, 5, 8, 13, 21 }; foreach (var number in from f in fibonacci where f > 5 select f) { Console.WriteLine(number); }
1.3 匿名型別與using
using( var connection = new SqlConnection(connectionString)) { connection.Open(); // ...... }
2. 陣列初始化器
使用關鍵字new初始化陣列。
var fibonacci = new int[]{ 1, 1, 2, 3, 5, 8, 13, 21 };
3. 匿名泛型方法
Func<long, long> Factorial = delegate(long n) { if (n == 1) { return 1; } long result = 1; for (int i = 2; i <= n; i++) { result *= i; } return result; }; Console.WriteLine(Factorial(6));
// using System.Diagnostics; Func<long, long> Factorial = delegate(long n) { return n > 1 ? n * (long)(new StackTrace() .GetFrame(0) .GetMethod() .Invoke(null, new object[] { n - 1 })) : n; }; Console.WriteLine(Factorial(6));
4. 自動實現屬性
public string ProductName { get; set; }
設定只讀屬性:
public string ProductName { get; private set; }
5.物件初始化器和集合初始化器
物件初始化器:在不呼叫類的建構函式以宣告性方式建立一個新的物件,並設定該物件的各個屬性的值。
Product product = new Product { ProductID = 1, ProductName = "LINQ to Object", UnitPrice = 10m };
集合初始化器用來初始化一個集合。
List<int> num = new List<int> { 0, 1, 2, 6, 7, 8, 9 };
結合物件初始化器使用:
List<Product> products = new List<Product> { new Product { ProductID = 1, ProductName = "LINQ to Object", UnitPrice = 10m }, new Product { ProductID = 2, ProductName = "LINQ to ADO.NET", UnitPrice = 20m } };
6. Lambda表示式
Lambda表示式是一個匿名函式,它可以包含表示式和語句,並且可用於建立委託或表示式目錄樹型別。
Lambda表示式的基本形式:
(input parameters) => expression
其中,input parameters表示輸入引數,expression表示表示式。輸入引數的數量可以為空,1個或多個。
當輸入引數為空是,Lambda表示式左邊的()不能省略。
() => Console.WriteLine("Empty");
Func<DateTime> getDateTime = () => DateTime.Now;
當Lambda表示式的輸入引數的數量為1時,輸入引數的()可以省略。
x => x * x;
當Lambda表示式的輸入引數的數量大於1時,輸入引數的()是必須的,且引數之間使用逗號分隔。
(x, y) => x * y;
Lambda的delegate形式轉換:
delegate(int x) { return x * x; };
7. 查詢表示式
var products = from p in ctx.Products where p.UnitPrice > 10m select p;
8. 擴充套件方法
擴充套件方法是C#中一個重要的特性,其對於LINQ的實現起著關鍵的作用。擴充套件方法在使用上類似於靜態方法,但在本質上其是例項方法。
擴充套件方法在引數前加上this關鍵字,引數的類似表示這個擴充套件方法要對這個型別進行擴充套件。
public static class Extensions { public static bool IsValidEmailAddress(this string value) { Regex regex = new Regex(@"^[\w\.]+@([\w]+\.)+[\w]{2,4}$"); return regex.IsMatch(value); } }
關聯隨筆:C# LINQ需求實現演化