物件初始設定式:具名和匿名類型 (Visual Basic)
物件初始設定式可讓您使用單一運算式來指定複雜物件的屬性。 其可用於建立具名類型與匿名型別的執行個體。
宣告
具名與匿名型別執行個體的宣告看起來幾乎完全相同,但其效果並不相同。 每個類別都有自己的功能與限制。 下列範例顯示使用物件初始設定式清單來宣告及初始化具名類別執行個體 Customer
的便利方式。 請注意,類別名稱是在 New
關鍵字後面指定。
Dim namedCust = New Customer With {.Name = "Terry Adams"}
匿名型別沒有可用的名稱。 因此,具現化匿名型別不得包含類別名稱。
Dim anonymousCust = New With {.Name = "Hugo Garcia"}
兩個宣告的需求與結果不相同。 針對 namedCust
,具有 Name
屬性的 Customer
類別必須已經存在,且宣告會建立該類別的執行個體。 針對 anonymousCust
,編譯器會定義具有一個屬性 (稱為 Name
的字串) 的新類別,並建立該類別的新執行個體。
具名類型
物件初始設定式提供簡單方式來呼叫類型的建構函式,然後在單一陳述式中設定部分或所有屬性的值。 編譯器會針對陳述式叫用適當的建構函式:若未顯示任何引數,則為無參數的建構函式;若傳送一或多個引數,則為參數化建構函式。 之後,所指定屬性會依初始設定式清單中呈現的順序初始化。
初始設定式清單中的每個初始化都由類別成員的初始值指派所組成。 定義類別時,會判斷成員的名稱與資料類型。 在下列範例中,Customer
類別必須存在,且必須具有名為 Name
與 City
且可接受字串值的成員。
Dim cust0 As Customer = New Customer With {.Name = "Toni Poe",
.City = "Louisville"}
或者,您可以使用下列程式碼取得相同結果:
Dim cust1 As New Customer With {.Name = "Toni Poe",
.City = "Louisville"}
每個宣告都相當於下列範例,其會使用無參數的建構函式建立 Customer
物件,然後使用 With
陳述式來指定 Name
與 City
屬性的初始值。
Dim cust2 As New Customer()
With cust2
.Name = "Toni Poe"
.City = "Louisville"
End With
若 Customer
類別包含參數化建構函式,則其可讓您以 Name
的值傳送;例如,您也能以下列方式宣告及初始化 Customer
物件:
Dim cust3 As Customer =
New Customer("Toni Poe") With {.City = "Louisville"}
' --or--
Dim cust4 As New Customer("Toni Poe") With {.City = "Louisville"}
您不需要初始化所有屬性,如下列程式碼所示。
Dim cust5 As Customer = New Customer With {.Name = "Toni Poe"}
然而,初始化清單不得為空白。 未初始化的屬性會保留其預設值。
具名類型的型別推斷
您可以結合物件初始設定式與本機型別推斷,來縮短 cust1
宣告的程式碼。 這可讓您省略變數宣告中的 As
子句。 變數的資料類型是從指派所建立的物件類型推斷。 在下列範例中,cust6
的類型為 Customer
。
Dim cust6 = New Customer With {.Name = "Toni Poe",
.City = "Louisville"}
關於具名類型的備註
類別成員無法在物件初始設定式清單中初始化一次以上。
cust7
的宣告會導致錯誤。'' This code does not compile because Name is initialized twice. ' Dim cust7 = New Customer With {.Name = "Toni Poe", ' .City = "Louisville", ' .Name = "Blue Yonder Airlines"}
成員可用於初始化本身或其他欄位。 若在初始化成員之前存取該成員 (如下列
cust8
宣告所示),將會使用預設值。 請記得當處理使用物件初始設定式的宣告時,第一件事就是叫用適當的建構函式。 之後,初始設定式清單中的個別欄位會初始化。 在下列範例中,會為Name
指派cust8
的預設值,並在cust9
中指派初始化的值。Dim cust8 = New Customer With {.Name = .Name & ", President"} Dim cust9 = New Customer With {.Name = "Toni Poe", .Title = .Name & ", President"}
下列範例使用
cust3
與cust4
的參數化建構函式來宣告及初始化cust10
與cust11
。Dim cust10 = New Customer("Toni Poe") With {.Name = .Name & ", President"} ' --or-- Dim cust11 As New Customer("Toni Poe") With {.Name = .Name & ", President"}
物件初始設定式可以巢狀化。 在下列範例中,
AddressClass
是具有兩個屬性 (City
與State
) 的類別,而Customer
類別具有AddressClass
執行個體的Address
屬性。Dim cust12 = New Customer With {.Name = "Toni Poe", .Address = New AddressClass With {.City = "Louisville", .State = "Kentucky"}} Console.WriteLine(cust12.Address.State)
初始化清單不得為空白。
初始化的執行個體不得為 Object 類型。
初始化的類別成員不得是共用成員、唯讀成員、常數或方法呼叫。
初始化的類別成員無法編制索引或限定。 下列範例會引發編譯器錯誤:
'' Not valid.
' Dim c1 = New Customer With {.OrderNumbers(0) = 148662}
' Dim c2 = New Customer with {.Address.City = "Springfield"}
匿名類型
匿名型別會使用物件初始設定式來建立您未明確定義及命名的新類型執行個體。 相反地,編譯器會根據您在物件初始設定式清單中指定的屬性產生類型。 因為未指定類型的名稱,所以稱為「匿名型別」。 例如,將下列宣告與先前的 cust6
宣告進行比較。
Dim cust13 = New With {.Name = "Toni Poe",
.City = "Louisville"}
唯一的語法差異在於,New
資料類型之後未指定任何名稱。 然而,會發生什麼情況相當不同。 編譯器會定義具有兩個屬性 (Name
與 City
) 的新匿名型別,並使用指定的值建立其執行個體。 型別推斷會判斷範例中 Name
與 City
的類型是否為字串。
警告
匿名型別的名稱由編譯器所產生,且每次編譯都不盡相同。 您的程式碼不應使用或依賴匿名型別的名稱。
因為類型的名稱無法使用,所以您無法使用 As
子句來宣告 cust13
。 必須推斷其類型。 若不使用晚期繫結,這會將匿名型別的使用限制為區域變數。
匿名型別為 LINQ 查詢提供重要支援。 如需在查詢中使用匿名型別的詳細資訊,請參閱匿名型別與 Visual Basic 中的 LINQ 簡介。
關於匿名型別的備註
一般而言,匿名型別宣告中的所有或大部分屬性都是索引鍵屬性,這些屬性是藉由在屬性名稱前面鍵入關鍵字
Key
來表示。Dim anonymousCust1 = New With {Key .Name = "Hugo Garcia", Key .City = "Louisville"}
如需索引鍵屬性的詳細資訊,請參閱索引鍵。
如同具名類型,匿名型別定義的初始設定式清單必須宣告至少一個屬性。
Dim anonymousCust = New With {.Name = "Hugo Garcia"}
宣告匿名型別的執行個體時,編譯器會產生相符的匿名型別定義。 屬性的名稱與資料類型會取自執行個體宣告,且會由編譯器包含在定義中。 屬性不會事先命名及定義,因為其可能適用於具名類型。 推斷其類型。 您無法使用
As
子句來指定屬性的資料類型。匿名型別也可以透過數種方式來建立其屬性的名稱與值。 例如,匿名型別屬性可以同時接受變數的名稱與值,或是另一個物件的屬性名稱與值。
' Create a variable, Name, and give it an initial value. Dim Name = "Hugo Garcia" ' Variable anonymousCust2 will have one property, Name, with ' "Hugo Garcia" as its initial value. Dim anonymousCust2 = New With {Key Name} ' The next declaration uses a property from namedCust, defined ' in an earlier example. After the declaration, anonymousCust3 will ' have one property, Name, with "Terry Adams" as its value. Dim anonymousCust3 = New With {Key namedCust.Name}
如需定義匿名型別屬性之選項的詳細資訊,請參閱操作說明:推斷匿名型別宣告中的屬性名稱與類型。