- Feature introduced in C# 3.0
- LINQ 查詢簡介 (C#)
- 所有的 LINQ 查詢作業都包含三個不同的動作:
- 取得資料來源
- 建立查詢
- 查詢與執行查詢不同,查詢只建立變數並不會擷取任何資料
- 執行查詢 Code
- Code
class IntroToLINQ
{
static void Main()
{
// The Three Parts of a LINQ Query:
// 1. Data source.
int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
// 2. Query creation.
// numQuery is an IEnumerable< int>
var numQuery =
from num in numbers
where (num % 2) == 0
select num;
// 3. Query execution.
foreach (int num in numQuery)
{
Console.Write("{0,1} ", num);
}
}
}
- Linq 執行查詢分兩種:
- 延後執行查詢
- 因執行"建立查詢"的作業將會延後至使用 foreach 陳述式時,每次取回相同條件查詢結果,稱為 "Deferred Execution"
- 因查詢變數本身將部會保留任何查詢結果,所以可以多次的查詢變數已取得最後的結果
- Code:如上列的範例
- 強制立即執行
- 執行"彙總韓式"(Average, Sum, Count ... 等等)或者"查詢結果"(ToList, FirstOrDefault, First... 等等),取出回傳值
- 立即執行的方法,大多使用 Extension Method (擴充方法)
- Code 待補
delegate int del(int i);
static void Main(string[] args)
{
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
}
- 查詢語法中直接使用 Lambda 運算式,而是在方法呼叫中使用它們,因此查詢運算式可以包含方法呼叫
- Code
class SimpleLambda
{
static void Main()
{
// Data source.
int[] scores = { 90, 71, 82, 93, 75, 82 };
// The call to Count forces iteration of the source
// 左邊的 n 是輸入變數,代表資料來源中的每一個物件
int highScoreCount = scores.Where(n => n > 80).Count();
Console.WriteLine("{0} scores are greater than 80", highScoreCount);
// Outputs: 4 scores are greater than 80
}
}
- Extension
Method 擴充方法 (C# 程式設計手冊)
- 建議您應謹慎地實作擴充方法,而且只有在必要時才實作
- 使用擴充方法來擴充無法變更其原始程式碼的類型時,會有類型實作的變更導致擴充方法中斷的風險
- 定義
- 靜態 (static) 類別中宣告靜態方法
- 透過第一個參數前加上 this 關鍵字,指定要擴充的類別
- 如下圖,C# 中已經實做許多擴充方法
class Program
{
static void Main(string[] args)
{
string sName = "Lyndon";
sName.Print();
int nSum = 50;
Console.WriteLine(nSum.Add(100).Add(30));
}
}
///
/// 1. 靜態類別中
///
public static class Extensions
{
///
/// 2. 宣告靜態方法 Print
/// 3. 第一個參數前加上 this 關鍵字
/// 4. 指定要擴充的類別 (string)
///
/// The aString.
public static void Print(this string aString)
{
Console.WriteLine(aString.ToUpper());
}
///
/// Adds the specified aint.
///
/// The aint.
/// The int add number.
///
public static int Add(this int aInt, int nAdd)
{
return aInt + nAdd;
}
}
Result
///
/// implicitly typed
///
var i = 10;
var s = "Lyndon";
///
/// explicitly typed
/// 編譯器 (Compiler) 判斷型別
///
int i = 10;
string s = "Lyndon";
Case1 (Linq IEnumerable<string>)
// 查詢結果的型別可以明確陳述為 IEnumerable< string>,所以允許使用 var,但不需要這麼做
// Example #1: var is optional because
// the select clause specifies a string
string[] words = { "apple", "strawberry", "grape", "peach", "banana" };
var wordQuery = from word in words
where word[0] == 'g'
select word;
// Because each element in the sequence is a string,
// not an anonymous type, var is optional here also.
foreach (string s in wordQuery)
{
Console.WriteLine(s);
}
- Case2 (Linq anonymous type)
// 名型別的集合,而且只有編譯器 (Compiler) 才可以存取該型別的名稱,所以必須使用 var
// Example #2: var is required because
// the select clause specifies an anonymous type
var custQuery = from cust in customers
where cust.City == "Phoenix"
select new { cust.Name, cust.Phone };
// foreach 反覆運算變數 item 也必須是隱含型別
// var must be used because each item
// in the sequence is an anonymous type
foreach (var item in custQuery)
{
Console.WriteLine("Name={0}, Phone={1}", item.Name, item.Phone);
}
public class User
{
public string Name { get; set; }
public int Age { get; set; }
}
User user = new User { Name = "Lyndon", Age = 30 };
public class Initializers
{
public void function()
{
var user = new { Name = "Lyndon", Age = 30 };
}
}
- Ref
- C#版本3~5的新特性
- C# 指南
- C# 筆記:Expression Trees
- https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7Ew6qCNNbeSoYZBfSB-Lv6D523LpTezsXJjzA35naDozQpcTjivej1tV3B7Aa5BvJHYyawR1MY6cnPR0o5_Yb7FsOil7XJ9YLUqup9QEVSuguWK39ETm7eNqLtZX3BDqgnkuAE8lnCPHh/s1600/AnonymousFunctionCmap.jpg
- C# 筆記:擴充方法
沒有留言:
張貼留言