在去年P(guān)DC2005上,在發(fā)布C#2.0 (C# Whidbey)的同時(shí),微軟也同時(shí)展示了它們?cè)贑# 3.0上的一些計(jì)劃。在提到一系列新的語(yǔ)言特性如語(yǔ)言集成查詢(LINQ)等,Redmond同時(shí)也介紹了一個(gè)新的特性--匿名類(lèi)型。本文詳細(xì)介紹了匿名類(lèi)型。
匿名類(lèi)型定義
C#3.0規(guī)范將匿名類(lèi)型描述為從對(duì)象初始化器(object initializer)自動(dòng)推斷和生成的元組類(lèi)型。在你能夠充分領(lǐng)會(huì)這一定義之前,你需要了解"對(duì)象初始化器"的概念,它是匿名類(lèi)型特性的基礎(chǔ)。
對(duì)象初始化器給一個(gè)對(duì)象的一個(gè)或者多個(gè)域或者屬性指定值。這就意味著你可以通過(guò)一系列諸如{a=10,b=20}這樣的賦值操作指定某個(gè)對(duì)象的一系列屬性。換句話來(lái)說(shuō),一個(gè)匿名類(lèi)型是原來(lái)不存在的,并且沒(méi)有在代碼中明確指定的。
注意,編譯器是在編譯時(shí)創(chuàng)建匿名類(lèi)型而非運(yùn)行時(shí)。
你可以通過(guò)ILDASM(IL分解器)來(lái)分解獲得:
var p1 = new {Name = "A", Price = 3};
在編譯時(shí)刻,編譯器使用對(duì)象初始化器推斷的屬性來(lái)傳見(jiàn)一個(gè)新的匿名類(lèi)型。因而,新類(lèi)型將會(huì)擁有Name和Price的屬性。Get和Set方法和保存這些屬性的相應(yīng)的私有變量,會(huì)自動(dòng)的生成。在運(yùn)行時(shí),此類(lèi)型的一個(gè)實(shí)例會(huì)被創(chuàng)建,這個(gè)實(shí)例的屬性將會(huì)被設(shè)置為對(duì)象初始化器中指定的值。
C#內(nèi)部
你可能很驚奇的發(fā)現(xiàn),你可以只定義一些屬性的名稱(chēng)以及它們的值,C# 3.0會(huì)自動(dòng)的從它們那里創(chuàng)建類(lèi)。這是怎么做到的呢?檢查一下編譯器的處理吧。
這樣開(kāi)始一行代碼:
var p1 = new {Name = "A", Price = 3};
當(dāng)C# 3.0編譯器遇到這樣的一個(gè)請(qǐng)求的時(shí)候,它將在后臺(tái)將其轉(zhuǎn)化成更加清楚的表達(dá),如下:
class __Anonymous1
{
private string name ;
private int price;
public string Name{ get { return name; } set { name = value ; } }
public int Price{ get { return price; } set { price= value ; } }
}
__Anonymous1 p1 = new __Anonymous1();
p1.Name = "A";
pt.Price =3
實(shí)例學(xué)習(xí)
你需要安裝Visual Studio 2005和.net 2.0,然后你可以從這里下載到LINQ技術(shù)的預(yù)覽版本。
如果你安裝了Visual Studio 2005,你可以看到在Visual C#下多了3個(gè)和LINQ預(yù)覽有關(guān)的工程模板:LINQ Console Application, LINQ Windows Application, 和LINQ Library。
你可以這樣創(chuàng)建一個(gè)使用匿名類(lèi)型的工程:
1. 打開(kāi)Visual Studio 2005編輯器,創(chuàng)建一個(gè)新工程,選擇LINQ Console作為工程模板;
2. 將新工程命名為AnonTypes并且點(diǎn)擊OK;
3. 在編輯器里輸入如下代碼:
// Program.cs
using System;
using System.Query;
using System.Data.DLinq;
namespace AnonTypes
{
class Program
{
static void Main(string[] args)
{
var p1 = new {Name = "A", Price = 3};
Console.WriteLine("Name = {0}\nPrice = {1}",p1.Name, p1.Price);
Console.ReadLine();
}
}
}
4. 編譯程序
5. 執(zhí)行程序,獲得如下結(jié)果:
Name = A
Price = 3
如果你沒(méi)有Visual Studio 2005,你仍然可以通過(guò)命令行來(lái)編譯你的代碼:
C:\Program Files\LINQ Preview\Bin\Csc.exe
/reference:"C:\Program Files\LINQ Preview\Bin\System.Data.DLinq.dll"
/reference: System.dll
/reference:"C:\Program Files\LINQ Preview\Bin\System.Query.dll"
/out:AnonTypes.exe /target:exe Program.cs
盡管你沒(méi)有清晰的在代碼里定義一個(gè)類(lèi),但是C#編譯器自動(dòng)做了如下工作:
1. 解析類(lèi)型
2. 創(chuàng)建一個(gè)新的類(lèi)(擁有name和price屬性)
3. 使用這個(gè)類(lèi)來(lái)初始化一個(gè)新對(duì)象
4. 將傳來(lái)的參數(shù)指定給對(duì)象
匿名類(lèi)型定義
C#3.0規(guī)范將匿名類(lèi)型描述為從對(duì)象初始化器(object initializer)自動(dòng)推斷和生成的元組類(lèi)型。在你能夠充分領(lǐng)會(huì)這一定義之前,你需要了解"對(duì)象初始化器"的概念,它是匿名類(lèi)型特性的基礎(chǔ)。
對(duì)象初始化器給一個(gè)對(duì)象的一個(gè)或者多個(gè)域或者屬性指定值。這就意味著你可以通過(guò)一系列諸如{a=10,b=20}這樣的賦值操作指定某個(gè)對(duì)象的一系列屬性。換句話來(lái)說(shuō),一個(gè)匿名類(lèi)型是原來(lái)不存在的,并且沒(méi)有在代碼中明確指定的。
注意,編譯器是在編譯時(shí)創(chuàng)建匿名類(lèi)型而非運(yùn)行時(shí)。
你可以通過(guò)ILDASM(IL分解器)來(lái)分解獲得:
var p1 = new {Name = "A", Price = 3};
在編譯時(shí)刻,編譯器使用對(duì)象初始化器推斷的屬性來(lái)傳見(jiàn)一個(gè)新的匿名類(lèi)型。因而,新類(lèi)型將會(huì)擁有Name和Price的屬性。Get和Set方法和保存這些屬性的相應(yīng)的私有變量,會(huì)自動(dòng)的生成。在運(yùn)行時(shí),此類(lèi)型的一個(gè)實(shí)例會(huì)被創(chuàng)建,這個(gè)實(shí)例的屬性將會(huì)被設(shè)置為對(duì)象初始化器中指定的值。
C#內(nèi)部
你可能很驚奇的發(fā)現(xiàn),你可以只定義一些屬性的名稱(chēng)以及它們的值,C# 3.0會(huì)自動(dòng)的從它們那里創(chuàng)建類(lèi)。這是怎么做到的呢?檢查一下編譯器的處理吧。
這樣開(kāi)始一行代碼:
var p1 = new {Name = "A", Price = 3};
當(dāng)C# 3.0編譯器遇到這樣的一個(gè)請(qǐng)求的時(shí)候,它將在后臺(tái)將其轉(zhuǎn)化成更加清楚的表達(dá),如下:
class __Anonymous1
{
private string name ;
private int price;
public string Name{ get { return name; } set { name = value ; } }
public int Price{ get { return price; } set { price= value ; } }
}
__Anonymous1 p1 = new __Anonymous1();
p1.Name = "A";
pt.Price =3
實(shí)例學(xué)習(xí)
你需要安裝Visual Studio 2005和.net 2.0,然后你可以從這里下載到LINQ技術(shù)的預(yù)覽版本。
如果你安裝了Visual Studio 2005,你可以看到在Visual C#下多了3個(gè)和LINQ預(yù)覽有關(guān)的工程模板:LINQ Console Application, LINQ Windows Application, 和LINQ Library。
你可以這樣創(chuàng)建一個(gè)使用匿名類(lèi)型的工程:
1. 打開(kāi)Visual Studio 2005編輯器,創(chuàng)建一個(gè)新工程,選擇LINQ Console作為工程模板;
2. 將新工程命名為AnonTypes并且點(diǎn)擊OK;
3. 在編輯器里輸入如下代碼:
// Program.cs
using System;
using System.Query;
using System.Data.DLinq;
namespace AnonTypes
{
class Program
{
static void Main(string[] args)
{
var p1 = new {Name = "A", Price = 3};
Console.WriteLine("Name = {0}\nPrice = {1}",p1.Name, p1.Price);
Console.ReadLine();
}
}
}
4. 編譯程序
5. 執(zhí)行程序,獲得如下結(jié)果:
Name = A
Price = 3
如果你沒(méi)有Visual Studio 2005,你仍然可以通過(guò)命令行來(lái)編譯你的代碼:
C:\Program Files\LINQ Preview\Bin\Csc.exe
/reference:"C:\Program Files\LINQ Preview\Bin\System.Data.DLinq.dll"
/reference: System.dll
/reference:"C:\Program Files\LINQ Preview\Bin\System.Query.dll"
/out:AnonTypes.exe /target:exe Program.cs
盡管你沒(méi)有清晰的在代碼里定義一個(gè)類(lèi),但是C#編譯器自動(dòng)做了如下工作:
1. 解析類(lèi)型
2. 創(chuàng)建一個(gè)新的類(lèi)(擁有name和price屬性)
3. 使用這個(gè)類(lèi)來(lái)初始化一個(gè)新對(duì)象
4. 將傳來(lái)的參數(shù)指定給對(duì)象

