HOW TO:在匿名型別宣告中推斷屬性名稱和型別 (Visual Basic)
匿名型別不提供為屬性直接指定資料型別的機制。所有屬性的型別都是以推斷方式決定。在下列範例中,Name 和 Price 的型別會直接從初始化給它們的值來推斷。
' Variable product is an instance of a simple anonymous type.
Dim product = New With {Key .Name = "paperclips", .Price = 1.29}
匿名型別也可以從其他來源推斷屬性名稱和型別。下列各節會列出可以進行推斷的情況,並舉出幾個不能進行推斷的情況。
成功推斷
匿名型別可以從下列來源推斷屬性名稱和型別:
變數名稱:匿名型別 anonProduct 具有兩個屬性,即 productName 和 productPrice。這些屬性的資料型別會是原始變數的資料型別,分別是 String 和 Double。
Dim productName As String = "paperclips" Dim productPrice As Double = 1.29 Dim anonProduct = New With {Key productName, Key productPrice} ' To create uppercase variable names for the new properties, ' assign variables productName and productPrice to uppercase identifiers. Dim anonProduct1 = New With {Key .Name = productName, Key .Price = productPrice}
其他物件的屬性或欄位名稱:例如,假設有個 car 物件,其具有 CarClass 型別,包含 Name 和 ID 屬性。若要建立新的匿名型別執行個體 car1,並利用 car 物件中的值初始化該執行個體的 Name 和 ID 屬性,您可以撰寫下列程式碼:
Dim car1 = New With {Key car.Name, Key car.ID}
使用上述宣告,可省去用更長一行程式碼來定義 car2 匿名型別的麻煩。
Dim car2 = New With {Key .Name = car.Name, Key .ID = car.ID}
XML 成員名稱:
Dim books = <Books> <Book Author="Jesper Aaberg"> Advanced Programming Methods </Book> </Books> Dim anon = New With {books...<Book>}
替 anon 產生的型別會有一個屬於 IEnumerable(Of XElement) 型別的屬性,即 Book。
沒有參數的函式,例如下列範例中的 SomeFunction。
Dim sc As New SomeClass
Dim anon1 = New With {Key sc.SomeFunction()}
下列程式碼中的 anon2 變數是個具有一個屬性 (以 First 命名的字元) 的匿名型別。這個程式碼會顯示字母 "E",即 First 函式所傳回的字母。
Dim aString As String = "Example String" Dim anon2 = New With {Key aString.First()} ' The variable anon2 has one property, First. Console.WriteLine(anon2.First)
推斷失敗
在許多情況下名稱推斷會失敗,包括:
因為叫用方法、建構函式 (Constructor) 或是需要引數的參數化屬性而衍生的推斷:上述 anon1 宣告中的 someFunction 如果有一個或多個引數,該宣告就會失敗。
' Not valid.
' Dim anon3 = New With {Key sc.someFunction(someArg)}
只要指派給新的屬性名稱,就可以解決這個問題。
' Valid.
Dim anon4 = New With {Key .FunResult = sc.someFunction(someArg)}
從複雜運算式衍生的推斷:
Dim aString As String = "Act " ' Not valid. ' Dim label = New With {Key aString & "IV"}
只要將運算式的結果指派給一個屬性名稱,就可以解決這個錯誤。
' Valid. Dim label1 = New With {Key .someLabel = aString & "IV"}
為多個屬性進行推斷會產生兩個以上的同名屬性:例如在稍早範例的宣告中,您不能將 product.Name 和 car1.Name 都列為同一個匿名型別的屬性。這是因為經推斷後,這些屬性的識別項都會是 Name。
' Not valid.
' Dim anon5 = New With {Key product.Name, Key car1.Name}
只要將值指派給不同的屬性名稱,就可以解決這個問題。
' Valid. Dim anon6 = New With {Key .ProductName = product.Name, Key .CarName = car1.Name}
請注意,大小寫的不同 (變更字母的大小寫) 並不會形成名稱上的差異。
Dim price = 0
' Not valid, because Price and price are the same name.
' Dim anon7 = New With {Key product.Price, Key price}
某個屬性的初始型別和初始值取決於另一個尚未建立的屬性。例如,除非 .LastName 已經初始化,否則 .IDName = .LastName 在匿名型別宣告中是無效的。
' Not valid.
' Dim anon8 = New With {Key .IDName = .LastName, Key .LastName = "Jones"}
在這個範例中,只要顛倒屬性的宣告順序,就可以解決這個問題。
' Valid. Dim anon9 = New With {Key .LastName = "Jones", Key .IDName = .LastName}
匿名型別的屬性名稱與 Object 之某個成員的名稱相同。例如,下列宣告會失敗,原因是 Equals 是 Object 的方法。
' Not valid.
' Dim relationsLabels1 = New With {Key .Equals = "equals", Key .Greater = _
' "greater than", Key .Less = "less than"}
只要變更屬性名稱,就可以解決這個問題:
' Valid Dim relationsLabels2 = New With {Key .EqualString = "equals", Key .GreaterString = "greater than", Key .LessString = "less than"}