物件初始設定式:具名和匿名型別 (Visual Basic)

物件初始設定式可以讓您使用單一運算式來指定複雜物件的屬性, 而且可以用來建立具名型別和匿名型別的執行個體 (Instance)。

宣告

具名和匿名型別之執行個體的宣告看起來相同,但是效果不同。 每個分類都有各自的功能和限制。 下列範例顯示使用物件初始設定式清單來宣告及初始化具名類別 Customer 之執行個體的方便方法。 請注意,類別 (Class) 的名稱指定在關鍵字 New 後面。

Dim namedCust = New Customer With {.Name = "Terry Adams"}

匿名型別沒有可以使用的名稱。 因此匿名型別的執行個體化 (Instantiation) 無法包含類別名稱。

Dim anonymousCust = New With {.Name = "Hugo Garcia"}

兩個宣告的需求和結果都不同。 對於 namedCust,具有 Name 屬性的 Customer 類別必須已經存在,並由宣告建立該類別的執行個體。 對於 anonymousCust,則由編譯器 (Compiler) 定義具有一個屬性的新類別,也就是名為 Name 的字串,然後再建立該類別的新執行個體。

具名型別

物件初始設定式提供了一個簡單方法,可以呼叫型別的建構函式 (Constructor),然後在單一陳述式中設定部分或所有屬性的值。 編譯器會叫用 (Invoke) 陳述式的適當建構函式:如果沒有引數則叫用預設建構函式,如果傳送了一個或多個引數則叫用參數型建構函式。 然後,指定的屬性會以初始設定式清單中出現的順序進行初始化。

初始設定式清單中的每一個初始設定,各會指派一個初始值給類別的成員。 成員的名稱和資料型別則是在定義類別時決定。 在下列範例中,必須有 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 的宣告所示,則會使用預設值。 請記住,處理使用物件初始設定式的宣告時,發生的第一件事是叫用適當的建構函式。 接著會初始化初始設定式清單中的個別欄位。 在下列範例中,會為 cust8 指派 Name 的預設值,並在 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 類別具有 Address 屬性,該屬性是 AddressClass 的執行個體。

    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"}

匿名型別

匿名型別會使用物件初始設定式,建立您未明確定義及命名的新型別執行個體。 並由編譯器根據您在物件初始設定式清單中指定的屬性產生型別。 因為不指定型別的名稱,所以才稱為「匿名型別」(Anonymous Type)。 例如,請比較下列宣告與先前的 cust6 宣告。

Dim cust13 = New With {.Name = "Toni Poe", 
                       .City = "Louisville"}

唯一的語法差異是資料型別的 New 後面未指定名稱。 但是,結果有相當大的差異。 編譯器會定義新的匿名型別,該型別具有兩個屬性 Name 和 City,並且以指定值建立執行個體。 型別推斷會判斷範例中 Name 和 City 的型別為字串。

警告

匿名型別的名稱是由編譯器產生,而且每次編譯時產生的名稱都不同。 您的程式碼不應該使用或固定參考匿名型別的名稱。

因為型別的名稱無法使用,所以您無法使用 As 子句宣告 cust13。 其型別必須由推斷得出。 不需使用晚期繫結 (Late Binding),上述限制即會將匿名型別的使用方式限制在區域變數。

匿名型別可對 LINQ 查詢提供重要支援。 如需在查詢中使用匿名型別的詳細資訊,請參閱匿名型別 (Visual Basic)Visual Basic 中的 LINQ 簡介

匿名型別的備註

  • 通常,匿名型別宣告中的大部分或所有屬性都是索引鍵屬性,藉由在屬性名稱前輸入關鍵字 Key 來表示。

    
    Dim anonymousCust1 = New With {Key .Name = "Hugo Garcia", 
                                   Key .City = "Louisville"}
    

    如需索引鍵屬性的詳細資訊,請參閱 Key (Visual Basic)

  • 和具名型別相同,匿名型別定義的初始設定式清單必須宣告至少一個屬性。

    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}
    

    如需在匿名型別中定義屬性之選項的詳細資訊,請參閱 HOW TO:在匿名型別宣告中推斷屬性名稱和型別 (Visual Basic)

請參閱

工作

HOW TO:在匿名型別宣告中推斷屬性名稱和型別 (Visual Basic)

HOW TO:宣告匿名型別的執行個體 (Visual Basic)

HOW TO:使用物件初始設定式宣告物件 (Visual Basic)

參考

Key (Visual Basic)

概念

區域型別推斷 (Visual Basic)

匿名型別 (Visual Basic)

Visual Basic 中的 LINQ 簡介

具名和匿名型別比較 (Visual Basic)