日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > C# >内容正文

C#

vs2008中C#3.0语言的新特性

發(fā)布時(shí)間:2024/4/17 C# 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 vs2008中C#3.0语言的新特性 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

看了YJingLee's Blog的文章,收獲很大,以下文章轉(zhuǎn)自http://www.cnblogs.com/lyj/archive/2008/01/08/1030525.html

?

總體來(lái)說(shuō),Visual Studio 2008和.NET 3.5是建立在.NET2.0核心的基礎(chǔ)之上,.NET2.0核心本身將不再變化(如果不了解.NET2.0的朋友,請(qǐng)參看MSDN或者一些經(jīng)典的書籍),C# 3.0新語(yǔ)言特性在.NET2.0基礎(chǔ)上進(jìn)行了改進(jìn),這些改進(jìn)的功能可以大大簡(jiǎn)化我們編寫程序。關(guān)于C# 3.0新語(yǔ)言特性在博客園里的很多朋友都介紹了,我在這里簡(jiǎn)單介紹一下,記錄自己所學(xué)的東西,也為后面的LINQ打下基礎(chǔ)。

C# 3.0新語(yǔ)言特性和改進(jìn)包括:

  • 自動(dòng)屬性(Auto-Implemented Properties)
  • 隱含類型局部變量(Local Variable Type Inference)
  • 匿名類型(Anonymous Types)
  • 對(duì)象與集合初始化器(Object and Collection Initializers)
  • 擴(kuò)展方法(Extension Methods)
  • Lambda表達(dá)式和Lambda表達(dá)式樹(shù) (Lambda Expression and Lambda Expression Trees)

?

自動(dòng)屬性可以避免原來(lái)這樣我們手工聲明一個(gè)私有成員變量以及編寫get/set邏輯,在VS2008中可以像下面這樣編寫一個(gè)類,編譯器會(huì)自動(dòng)地生成私有變量和默認(rèn)的get/set 操作。你也可以分別定義get和set的“protected”等訪問(wèn)級(jí)別。

在.Net2.0框架下,我們可以這樣寫一個(gè)User類:

public class User { private int _id; private string _name; private int _age; public int Id { get { return _id; } set { _id = value; } } public string Name { get { return _name; } set { _name = value; } } public int Age { get { return _age; } set { _age = value; } } }

現(xiàn)在,可以這樣簡(jiǎn)化:

public class User { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } }

像上面這樣的空的get/set屬性的話,它會(huì)自動(dòng)為你在類中生成一個(gè)私有成員變量,對(duì)這個(gè)變量實(shí)現(xiàn)一個(gè)公開(kāi)的getter 和setter。我們可以使用.NET開(kāi)發(fā)環(huán)境所提供的ildasm.exe(IL代碼反匯編器)工具來(lái)分析程序集或者模塊的內(nèi)容。我就不貼圖了。

?

C#3.0引進(jìn)了var這個(gè)新關(guān)鍵字,在聲明局部變量時(shí)可用于替代原先的類型名,即當(dāng)一個(gè)變量聲明標(biāo)識(shí)為var類型并且該范圍域中沒(méi)有var名稱類型存在,那么這個(gè)聲明就稱為隱含類型局部變量。如下(等同于//后面的顯式聲明):

var i = 5;//int var j = 23.56;//double var k = "C Sharp";//string var x;//錯(cuò)誤 var y = null;//錯(cuò)誤 var z = { 1, 2, 3 };//錯(cuò)誤

在調(diào)試狀態(tài)下,編譯器解釋如下

隱含類型局部變量要點(diǎn)

  • var為關(guān)鍵字,可以根據(jù)后面的初始化語(yǔ)句自動(dòng)推斷類型,這個(gè)類型為強(qiáng)類型。
  • 初始化語(yǔ)句必須為表達(dá)式,不可以為空。且編譯時(shí)可以推斷類型。一旦初始化之后,只可以存儲(chǔ)這種類型。
  • var聲明的僅限于局部變量,不可用于字段。亦可以用于for,foreach,using 等語(yǔ)句中。
  • 數(shù)組也可以作為隱含類型。
  • 初始化語(yǔ)句不能是一個(gè)自身的對(duì)象或者集合初始化器,但是他可以是包含一個(gè)對(duì)象或者初始化器的一個(gè)new表達(dá)式。
  • 如果局部變量聲明包含了多個(gè)聲明符,其類型必須相同。
  • 匿名類型(Anonymous Types)

    匿名類型允許定義行內(nèi)類型,無(wú)須顯式定義類型。常和var配合使用來(lái)聲明匿名類型。

    var p1 = new { Id = 1, Name = "YJingLee", Age = 22 };//屬性也不需要申明 var p2 = new { Id = 2, Name = "XieQing", Age = 25 }; p1 = p2;//p1,p2結(jié)構(gòu)相同,可以互相賦值

    在這里編譯器會(huì)認(rèn)為p1,p2相當(dāng)于:

    public class SomeType { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } }

    那么數(shù)組怎么定義呢?使用"new[]"關(guān)鍵字來(lái)聲明數(shù)組,加上數(shù)組的初始值列表。像這樣:

    var intArray = new[] { 2, 3, 5, 6 }; var strArray = new[] { "Hello", "World" }; var anonymousTypeArray = new[] { new { Name = "YJingLee", Age = 22 }, new { Name = "XieQing", Age = 25 } }; var a = intArray[0]; var b = strArray[0]; var c = anonymousTypeArray[1].Name;

    匿名類型要點(diǎn)

  • 可以使用new關(guān)鍵字調(diào)用匿名初始化器創(chuàng)建一個(gè)匿名類型的對(duì)象。
  • 匿名類型直接繼承自System. Object。
  • 匿名類型的成員是編譯器根據(jù)初始化器推斷而來(lái)的一些讀寫屬性。
  • ?

    對(duì)象初始化器 (Object Initializers) :

    .NET2.0框架中的類型非常依賴于屬性。當(dāng)生成對(duì)象實(shí)例和使用新的類型時(shí),在.Net2.0時(shí)候我們像這樣寫:

    User user = new User(); user.Id = 1; user.Name = "YJingLee"; user.Age = 22;

    在VS2008中,編譯器會(huì)自動(dòng)地生成合適的屬性setter代碼,使得原來(lái)幾行的屬性賦值操作可以在一行完成。我們可以這樣簡(jiǎn)化:像這樣,對(duì)象初始化器由一系列成員對(duì)象組成,其對(duì)象必須初始化,用逗號(hào)間隔,使用{}封閉。

    User user = new User { Id = 1, Name = "YJingLee", Age = 22 };

    又例如,我把二個(gè)人加到一個(gè)基于泛型的類型為User的List集合中:

    List<User> user = new List<User>{ new User{Id=1,Name="YJingLee",Age=22}, new User{Id=2,Name="XieQing",Age=25}, };

    如果有相同名字和類型的兩個(gè)對(duì)象初始化器將會(huì)產(chǎn)生相同的實(shí)例,可以相互賦值。例如:

    User user = new User { Id = 1, Name = "YJingLee", Age = 22 }; User user2 = new User { Id = 2, Name = "XieQing", Age = 25 }; user = user2;

    除了在初始化類時(shí)設(shè)置簡(jiǎn)單的屬性值外,對(duì)象初始化器特性也允許我們?cè)O(shè)置更復(fù)雜的嵌套(nested)屬性類型。例如我們可以在上面定義的User類型同時(shí)擁有一個(gè)屬于Address類型的叫“Address”的屬性:

    User user = new User { Id = 1, Name = "YJingLee", Age = 22, Address = new Address { City = "NanJing", Zip = 21000 } };

    集合初始化器(Collection Initializers):

    集合初始化器由一系列集合對(duì)象組成,用逗號(hào)間隔,使用{}封閉。
    集合初始化器可以簡(jiǎn)化把幾個(gè)對(duì)象一起添加到一個(gè)集合,編譯器會(huì)自動(dòng)為你做集合插入操作。例如我把七個(gè)數(shù)加到一個(gè)基于泛型的類型為int的List集合中

    List<int> num = new List<int> { 0, 1, 2, 6, 7, 8, 9 };

    對(duì)象與集合初始化器要點(diǎn)

  • 對(duì)象初始化器實(shí)際上利用了編譯器對(duì)對(duì)象中對(duì)外可見(jiàn)的字段和屬性進(jìn)行按序賦值。
  • 對(duì)象初始化器允許只給一部分屬性賦值,包括internal訪問(wèn)級(jí)別
  • 對(duì)象初始化器可以結(jié)合構(gòu)造函數(shù)一起使用,并且構(gòu)造函數(shù)初始化先于對(duì)象初始化器執(zhí)行。
  • 集合初始化器會(huì)對(duì)初始化器中的元素進(jìn)行按序調(diào)用ICollection<T>.Add(T)方法。
  • 注意對(duì)象初始化器和集合初始化器中成員的可見(jiàn)性和調(diào)用順序。
  • 對(duì)象與集合初始化器同樣是一種編譯時(shí)技術(shù)。
  • ?

    擴(kuò)展方法(Extension Methods)

    往往我們需要對(duì)CLR類型進(jìn)行一些操作,但苦于無(wú)法擴(kuò)展CLR類型的方法,只能創(chuàng)建一些helper方法,或者繼承類。我們來(lái)修改上面的User類:

    public class User { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string Read() { return "Id:" + Id + "姓名:" + Name + "年齡:" + Age; } }

    然后調(diào)用

    var user = new { Id = 1, Name = "YJingLee", Age = 22 }; var str = user.Read();

    現(xiàn)在有了擴(kuò)展方法就方便多了。

    擴(kuò)展方法允許開(kāi)發(fā)人員往一個(gè)現(xiàn)有的CLR類型的公開(kāi)契約(contract)中添加新的方法,而不用生成子類或者重新編譯原來(lái)的類型。擴(kuò)展方法有助于把今天動(dòng)態(tài)語(yǔ)言中流行的對(duì)duck typing的支持之靈活性,與強(qiáng)類型語(yǔ)言之性能和編譯時(shí)驗(yàn)證融合起來(lái)。——引用Scott博文

    擴(kuò)展方法是可以通過(guò)使用實(shí)例方法語(yǔ)法調(diào)用的靜態(tài)方法。效果上,使得附加的方法擴(kuò)展已存在類型和構(gòu)造類型成為可能。他可以對(duì)現(xiàn)有類功能進(jìn)行擴(kuò)充,從而使該類型的實(shí)例具有更多的方法(功能)。
    擴(kuò)展方法允許我們?cè)诓桓淖冊(cè)创a的情況下擴(kuò)展(即添加不能修改)現(xiàn)有類型中的實(shí)例方法。

    擴(kuò)展方法給我們一個(gè)怎樣的思路呢?我們一步一步做一下!
    首先聲明擴(kuò)展方法:通過(guò)指定關(guān)鍵字this修飾方法的第一個(gè)參數(shù)。注意擴(kuò)展方法僅可聲明在靜態(tài)類中。擴(kuò)展方法具備所有常規(guī)靜態(tài)方法的所有能力,可以使用實(shí)例方法語(yǔ)法來(lái)調(diào)用。接著就可以調(diào)用擴(kuò)展方法了。下面通過(guò)一個(gè)具體的實(shí)例分析一下:
    例如我們要檢查一個(gè)字符串變量是否是合法的電子郵件地址?在.Net2.0框架下像這樣:

    var email = "leeyongjing@gmail.com"; if (EmailValidator.IsValid(email)) { Response.Write("YJingLee提示:這是一個(gè)正確的郵件地址"); }

    而使用擴(kuò)展方法的話,我可以添加“IsValidEmailAddress()”方法到string類本身中去,該方法返回當(dāng)前字符串實(shí)例是否是個(gè)合法的字符串。

    if (email.IsValidEmailAddress()) { Response.Write("YJingLee提示:這是一個(gè)正確的郵件地址"); }

    我們是怎么把這個(gè)IsValidEmailAddress()方法添加到現(xiàn)有的string類里去的呢?先定義一個(gè)靜態(tài)類,再定義“IsValidEmailAddress”這個(gè)靜態(tài)的法來(lái)實(shí)現(xiàn)的。

    public static class Extensions//靜態(tài)類 { public static bool IsValidEmailAddress(this string s) //靜態(tài)方法和this { Regex regex = new Regex(@"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$"); return regex.IsMatch(s); } }

    注意,上面的靜態(tài)方法在第一個(gè)類型是string的參數(shù)變量前有個(gè)“this”關(guān)鍵詞,這告訴編譯器,這個(gè)特定的擴(kuò)展方法應(yīng)該添加到類型為“string”的對(duì)象中去。然后在IsValidEmailAddress()方法實(shí)現(xiàn)里,我可以訪問(wèn)調(diào)用該方法的實(shí)際string實(shí)例的所有公開(kāi)屬性/方法/事件,取決于它是否是合法電子郵件地址來(lái)返回true/false。

    擴(kuò)展方法不僅能夠應(yīng)用到個(gè)別類型上,也能應(yīng)用到.NET框架中任何基類或接口上。即可用于整個(gè).NET框架豐富的可組合的框架層擴(kuò)展。

    擴(kuò)展方法要點(diǎn)

  • 擴(kuò)展方法的本質(zhì)為將實(shí)例方法調(diào)用在編譯期改變?yōu)殪o態(tài)類中的靜態(tài)方法調(diào)用。事實(shí)上,它確實(shí)擁有靜態(tài)方法所具有的所有功能。
  • 擴(kuò)展方法的作用域是整個(gè)namespace可見(jiàn)的,并且可以通過(guò)using namespace來(lái)導(dǎo)入其它命名空間中的擴(kuò)展方法。
  • 擴(kuò)展方法的優(yōu)先級(jí):現(xiàn)有實(shí)例方法優(yōu)先級(jí)最高,其次為最近的namespace下的靜態(tài)類的靜態(tài)方法,最后為較遠(yuǎn)的namespace下的靜態(tài)類的靜態(tài)方法。
  • 擴(kuò)展方法是一種編譯時(shí)技術(shù),注意與反射等運(yùn)行時(shí)技術(shù)進(jìn)行區(qū)別,并慎重使用。
  • ?

    Lambda表達(dá)式

    我們從“所有字符串查找包含YJingLee子字符串”說(shuō)起。在C# 2.0中,匿名方法允許我們以內(nèi)聯(lián)的方式來(lái)實(shí)現(xiàn)委托實(shí)例,它提供強(qiáng)大的函數(shù)式編程語(yǔ)言,但是標(biāo)記顯得相當(dāng)?shù)娜唛L(zhǎng)和帶有強(qiáng)制性。我們使用C# 2.0 中的匿名方法查找,代碼如下:

    var inString = list.FindAll(delegate(string s) { return s.Indexof("YJingLee") >= 0; });

    現(xiàn)在可以使用C# 3.0帶來(lái)的Lambda表達(dá)式允許我們使用一種更接近人的思維、更自然的方式來(lái)實(shí)現(xiàn)類似于匿名方法同樣的效果,看下面的代碼多么簡(jiǎn)潔:

    var inString = list.FindAll(s => s.Indexof("YJingLee") >= 0);

    Lambda表達(dá)式格式:(參數(shù)列表)=>表達(dá)式或語(yǔ)句塊
    具體意義:定義Lambda接受參數(shù)列表,運(yùn)行表達(dá)式或語(yǔ)句塊返回表達(dá)式或語(yǔ)句塊的值傳給這個(gè)參數(shù)列表。

    Lambda表達(dá)式參數(shù)類型可以是隱式類型或顯式類型。在顯式列表中,每個(gè)參數(shù)的類型是顯式指定的,在隱式列表中,參數(shù)的類型由Lambda表達(dá)式出現(xiàn)的語(yǔ)境自動(dòng)推斷類型。
    Lambda表達(dá)式的參數(shù)列表可以有一個(gè)或多個(gè)參數(shù),或者無(wú)參數(shù)。在有單一的隱型參數(shù)的lambda表達(dá)式中,圓括號(hào)可以從參數(shù)列表中省略。
    例如:

    (x, y) => x * y;//多參數(shù),隱式類型=>表達(dá)式 x => x * 10;//單參數(shù),隱式類型=>表達(dá)式 x => { return x * 10; }; //單參數(shù),隱式類型=>語(yǔ)句塊 (int x) => x * 10;//單參數(shù),顯式類型=>表達(dá)式 (int x) => { return x * 10; };//單參數(shù),顯式類型=>語(yǔ)句塊 () => Console.WriteLine(); //無(wú)參數(shù)

    下面看這個(gè)例子:
    在前面的帖子中,我們寫了一個(gè)User類及增加了2個(gè)人,接下來(lái),我們使用由LINQ提供的新的Where和Average方法來(lái)返回集合中的人的一個(gè)子集,以及計(jì)算這個(gè)集合中的人的平均年齡:

    List<User> user = new List<User>{ new User{Id=1,Name="YJingLee",Age=22}, new User{Id=2,Name="XieQing",Age=25}, }; //獲取特定人時(shí)所用的過(guò)濾條件,p參數(shù)屬于User類型 var results = user.Where(p => p.Name == "YJingLee").ToList(); //用User對(duì)象的Age值計(jì)算平均年齡 var average = user.Average(p => p.Age);

    效果圖如下:

    對(duì)這個(gè)Lambda表達(dá)式做個(gè)簡(jiǎn)要分析:

    var resultsdelegate = user.Where(delegate(User p) { return p.Name == "YJingLee";// 返回一個(gè)布爾值 }); var averagedelegate = user.Average(delegate(User p) { return p.Age; });

    Lambda表達(dá)式L可以被轉(zhuǎn)換為委托類型D,需要滿足以下條件:
    L的參數(shù)類型要與D的參數(shù)個(gè)數(shù)相等,類型相同,返回類型相同,無(wú)論是表達(dá)式,還是語(yǔ)句塊。注意隱式類型要參與類型辨析。

    Lambda表達(dá)式樹(shù)

    Lambda表達(dá)式樹(shù)允許我們像處理數(shù)據(jù)(比如讀取,修改)一樣來(lái)處理Lambda表達(dá)式。我以一個(gè)例子簡(jiǎn)單說(shuō)明:

    Expression<Func<int, bool>> filter = n => (n * 3) < 5; BinaryExpression lt = (BinaryExpression)filter.Body; BinaryExpression mult = (BinaryExpression)lt.Left; ParameterExpression en = (ParameterExpression)mult.Left; ConstantExpression three = (ConstantExpression)mult.Right; ConstantExpression five = (ConstantExpression)lt.Right; var One = filter.Compile(); Console.WriteLine("Result: {0},{1}", One(5), One(1)); Console.WriteLine("({0} ({1} {2} {3}) {4})", lt.NodeType, mult.NodeType, en.Name, three.Value, five.Value);

    效果圖如下:

    Lambda表達(dá)式和Lambda表達(dá)式樹(shù)要點(diǎn)

  • Lambda表達(dá)式的參數(shù)類型可以忽略,因?yàn)榭梢愿鶕?jù)使用的上下文進(jìn)行推斷。
  • Lambda表達(dá)式的主體(body)可以是表達(dá)式,也可以是語(yǔ)句塊。
  • Lambda表達(dá)式傳入的實(shí)參將參與類型推斷,以及方法重載辨析。
  • Lambda表達(dá)式和表達(dá)式體可以被轉(zhuǎn)換為表達(dá)式樹(shù)。
  • 表達(dá)式樹(shù)允許lambda表達(dá)式能夠代表數(shù)據(jù)結(jié)構(gòu)替代表示為執(zhí)行代碼。
  • ????? 現(xiàn)在基本看完了和LINQ有關(guān)的C#新特性,其實(shí)現(xiàn)在看來(lái)微軟雖然進(jìn)行了很多改進(jìn),可以減少很多代碼量,但這些改進(jìn)是建立在降低代碼的可讀性上的,如果習(xí)慣之前版本的程序員會(huì)覺(jué)得代碼難以閱讀了。?

    轉(zhuǎn)載于:https://www.cnblogs.com/millen/archive/2009/02/12/1388922.html

    總結(jié)

    以上是生活随笔為你收集整理的vs2008中C#3.0语言的新特性的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。