1 引入匿名變量函數
在不少狀況下,咱們須要一種可以臨時將一批具備必定關聯的數據存放起來的對象;或者在某些狀況下,咱們對僅一個對象的「形狀」(如屬性的名字和類型等)比較感興趣。例如Book類,當它和其餘商品放在一塊兒進行查詢時,咱們可能僅對其名稱和價格感興趣,而且但願將這兩種屬性放在另一個單獨的臨時對象中以備從此使用。這時,咱們關注的僅僅是這個臨時對象具備Name和Price的屬性感興趣,至於它到底是什麼類型就可有可無了。然而,爲了使這樣一個對象得以存在,咱們不得不爲這個可有可無的類型寫上一大堆「樣本代碼」,無非就是定義一個如BookAsGood的類,其中無非也就是形如m_name和m_price的私有域和名爲Name與Price的公共可讀寫方法。代碼以下所示:this
public class BookAsGoodspa
{對象
// 定義一組私有成員變量繼承
private string m_name;索引
private double m_price;get
// 爲成員變量設置屬性編譯器
public string Namestring
{it
get
{
return this.m_name;
}
set
{
this.m_name = value;
}
}
public string Price
{
get
{
return this.m_price;
}
set
{
this.m_price = value;
}
}
}
若是像這樣封裝的成員太多,代碼量仍是很可怕的,而且維護的工做量也至關大。針對於這些問題,在C# 3.0中,咱們有了一個解決這種問題的捷徑,稱之爲匿名類型,它是C#匿名方法語法的擴展。
2 建立和使用引入匿名變量
var與new關鍵字一塊兒使用時,能夠建立匿名類型。匿名類型只是一個繼承了object的、沒有名稱的類。該類的定義從初始化器中推斷,相似於隱式類型化的變量。看下面的例子:
若是須要一個對象包含名字和價格,則能夠聲明以下:
// 表明一些書的一個匿名對象
var book = new { Name = "C#", Price = 100};
這會生成一個包含Name和Price屬性的對象。若是建立另外一個對象,以下所示:
var bookA = new { Name = "C# 3.0", Price = 80 };
其中,book和bookA的類型就是相同的。例如,咱們能夠這樣設置:
book = bookA;
若是所設置的值來自於另外一個對象,初始化器就能夠簡化。若是已經有一個包含Name和Price屬性的類,且有一個該類的實例b,則book對象就能夠初始化爲:
BookAsGood b = new BookAsGood();
var book = new { b.Name, b.Price };
在上面的代碼中,b對象的屬性名應投射爲新對象名book。因此book對象應有Name和Price屬性。
定義好以後,咱們就能夠這樣來訪問它的屬性,如:
// 像普通實例那樣訪問其中的屬性
Console.WriteLine(book.Name);
若是換成這樣訪問呢?如:
book.Name = "C# 3.0";
編譯器會報錯:沒法對屬性或索引器「AnonymousType#1.Name」賦值 -- 它是隻讀的。由於在這裏book的各個屬性只實現了get而沒有實現set。所謂「匿名類型」,能夠看到,咱們有了一個叫作book的實例,但卻沒有它的強類型名稱,在定義的時候將其定義爲隱式類型(事實上這也是強制的)。在給它指定屬性的時候也採用的對象初始化器的語法。在實際運行的時候,C#編譯器會爲它生成一個隱藏的類型名稱,咱們在程序中是不能對它進行訪問的。
一個匿名類型也是它的生存週期,那就是在生成它的方法以內。若是要向另外一個方法以參數的形式傳遞它,那就必須先將其轉換爲object類型(匿名類型也是從object直接派生而來的)。可是這樣會毀壞它內部屬性的強類型。若是須要保持內部屬性的強類型,因此建議在大多數狀況下,仍是採用傳統的類或者結構體來存儲數據比較可靠。
3 匿名變量與隱式類型變量的區別
l、隱式類型變量是指咱們能夠經過等號右邊的表達式,推斷出等號左邊該是那種類型。如:
var Name = "C#";
咱們能夠根據等號右邊的表達式「C#」,推斷出等號左邊的變量Name是string類型。
2、 匿名變量則是指根據這個類型的初始化函數,咱們能夠推導出和建立出這個類型的實例。這兩個特性不少時候是一塊兒做用的。如:
var book = new { Name = "C#", Price = 100};
上面的book就是一個匿名變量。其中的Name = "C#"和Price = 100又能夠分別看做是隱式類型變量。
轉自百度文庫