標籤:style blog java color 使用 資料
What‘s LINQ? Language Integrated Query 是也。說得再明白一些,這是程式設計語言的一種新特性,能夠將資料查詢語句整合到程式設計語言中。
主要還是因為現在的資料格式越來越多,資料庫、XML、數組、雜湊表……每一種都有自己操作資料的方式,學起來費事費力。於是,就有了LINQ誕生的理由——以一種統一的方式操作各種資料來源,減少資料訪問的複雜性。
通過GetMethods的方法,拿到string的所有方法,接下來,選出所有非靜態方法簽名
MethodInfo[] methods=typeof(string).getMethods();
var result = from m in methods
where m.IsStatic!=true
select m.Name;
foreach(var r in result)
{ Console.WriteLine(r.ToString()); }
Console.ReadLine();
看起來,var 有點像javascript 裡面的弱類型的變數聲明。但是,C#是強型別的,儘管你用var來聲明,編譯器還是可以根據上下文推倒出它當前的類型。
var result =(from m in methods where m.IsStatic!=true select m.Name).Distinct();
去掉重複記錄
class MyClass{ public string MethodName{get;set;} public int Overload{get;set;}}class Program{ MyClass mc=new MyClass{MethodName = "aaa",Overload=2};}
大括弧裡面的叫類初始化器,省去了建構函式,在new的同時,給對象的屬性賦值。
var result = from m in methods
where m.IsStatic != true
group m by m.Name into g
select new { MethodName = g.Key, Overload = g.Count() };
new一個新對象,居然連類名都不寫。沒錯,這就叫匿名類。
C # 3.0 的新特性
隱含類型局部變數
var age = 26; var username = "zhuye"; var userlist = new [] {"a","b","c"}; foreach(var user in userlist) Console.WriteLine(user);
讓編譯器自己推斷變數類型,但是既然讓編譯器推斷類型就必須聲明的時候賦值,而且不能是null值。注意,這隻能用於局部變數,用於欄位是不可以的。
var data = new {username = "zhuye",age = 26};
Console.WriteLine("username:{0} age:{1}", data.username, data.age);
匿名型別允許開發人員定義行內類型,無須顯式定義類型。常和var配合使用,var用於聲明匿名型別。
擴充方法
public static class helper { public static string MD5Hash(this string s) { return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(s,"MD5"); } public static bool In(this object o, IEnumerable b) { foreach(object obj in b) { if(obj==o) return true; } return false; } } // 調用擴充方法Console.WriteLine("123456".MD5Hash()); Console.WriteLine("1".In(new[]{"1","2","3"}));
對象初始化器
public class Person { public string username { get; set; } public int age { get; set; } public override string ToString() { return string.Format("username:{0} age:{1}", this.username, this.age); } } Person p = new Person() {username = "zhuye", age=26}; Console.WriteLine(p.ToString());
編譯器會自動為你做setter操作,使得原本幾行的屬性賦值操作能在一行中完成。這裡需要注意:
? 允許只給一部分屬性賦值,包括internal存取層級
? 可以結合建構函式一起使用,並且建構函式初始化先於對象初始化器執行
集合初始化器
public class Person { public string username { get; set; } public int age { get; set; } public override string ToString() { return string.Format("username:{0} age:{1}", this.username, this.age); } } var persons = new List { new Person {username = "a", age=1}, new Person {username = "b", age=2}}; foreach(var p in persons) Console.WriteLine(p.ToString());
Lambda運算式
var list = new [] { "aa", "bb", "ac" }; var result = Array.FindAll(list, s => (s.IndexOf("a") > -1)); foreach (var v in result) Console.WriteLine(v);
文法如下:
(參數列表) => 運算式或者語句塊
參數個數:可以有多個參數,一個參數,或者無參數。
運算式或者語句塊:這部分就是我們平常寫函數的實現部分(函數體)
var persons = new List { new Person {username = "a", age=19}, new Person {username = "b", age=20}, new Person {username = "a", age=21}, }; var selectperson = from p in persons where p.age >= 20 select p.username.ToUpper(); foreach(var p in selectperson) Console.WriteLine(p);
上面的查詢句法等價於下面的代碼:
var selectperson = persons.Where(p=>p.age>=20).Select(p=>p.username.ToUpper());
之後的拉姆運算式的功能大部分集中在實體與資料庫表項的操作,也就是各種DB操作,先不涉及了~~
Expression<Func<string, bool >> expr = o => o.Length > 10;
初次接觸Linq Lambda運算式的人可能會被搞迷糊,這樣的語句到底是什麼意思,怎麼樣工作,原理又是什麼。
逐級分析以上語句,分為兩個部分,以等號為界。
第一部分是變數類型的申明:Expression<Func<string, bool>> expr,表示expr這個變數是一個Linq Lambda運算式,這個運算式符合這樣的一種委託:bool DelegateName(string obj)。
第二部分是運算式的聲明o => o.Length > 10,這個“=>”是Lambda操作符,讀作“轉到”,必須把=>左右看成是一個整體,因為這實際是一個匿名方法,“=>”左邊是方法傳入參數的申明,右邊是函數體,如果用常規的表示方法,可以寫成如下形式:
bool MethodName(string o)
{
return o.Length > 10;
}
仔細觀察兩部分拆解以後的形式其實不難發現,第一部分的工作是定義了一個匿名的委託,而第二部分則是符合這個匿名委託的一個方法,由於這個方法沒有明確給定名稱,因此稱為匿名方法。