Objektinitierare: Namngivna och anonyma typer (Visual Basic)
Med objektinitierare kan du ange egenskaper för ett komplext objekt med hjälp av ett enda uttryck. De kan användas för att skapa instanser av namngivna typer och av anonyma typer.
Deklarationer
Deklarationer av instanser av namngivna och anonyma typer kan se nästan identiska ut, men deras effekter är inte desamma. Varje kategori har egna förmågor och begränsningar. I följande exempel visas ett praktiskt sätt att deklarera och initiera en instans av en namngiven klass, Customer
, med hjälp av en objektinitieringslista. Observera att namnet på klassen anges efter nyckelordet New
.
Dim namedCust = New Customer With {.Name = "Terry Adams"}
En anonym typ har inget användbart namn. Därför kan en instansiering av en anonym typ inte innehålla ett klassnamn.
Dim anonymousCust = New With {.Name = "Hugo Garcia"}
Kraven och resultaten av de två deklarationerna är inte desamma. För namedCust
måste en Customer
klass som har en Name
egenskap redan finnas och deklarationen skapar en instans av den klassen. För anonymousCust
definierar kompilatorn en ny klass som har en egenskap, en sträng med namnet Name
, och skapar en ny instans av den klassen.
Namngivna typer
Objektinitierare är ett enkelt sätt att anropa konstruktorn av en typ och sedan ange värdena för vissa eller alla egenskaper i en enda instruktion. Kompilatorn anropar lämplig konstruktor för -instruktionen: den parameterlösa konstruktorn om inga argument visas eller en parameteriserad konstruktor om ett eller flera argument skickas. Därefter initieras de angivna egenskaperna i den ordning de visas i initieringslistan.
Varje initiering i initieringslistan består av tilldelningen av ett initialt värde till en medlem i klassen. Namnen och datatyperna för medlemmarna bestäms när klassen har definierats. I följande exempel Customer
måste klassen finnas och ha medlemmar med namnet Name
och City
som kan acceptera strängvärden.
Dim cust0 As Customer = New Customer With {.Name = "Toni Poe",
.City = "Louisville"}
Du kan också få samma resultat med hjälp av följande kod:
Dim cust1 As New Customer With {.Name = "Toni Poe",
.City = "Louisville"}
Var och en av dessa deklarationer motsvarar följande exempel, som skapar ett Customer
objekt med hjälp av den parameterlösa konstruktorn och sedan anger initiala värden för Name
egenskaperna och City
med hjälp av en With
-instruktion.
Dim cust2 As New Customer()
With cust2
.Name = "Toni Poe"
.City = "Louisville"
End With
Customer
Om klassen innehåller en parameteriserad konstruktor som gör att du kan skicka in ett värde för Name
, kan du till exempel även deklarera och initiera ett Customer
objekt på följande sätt:
Dim cust3 As Customer =
New Customer("Toni Poe") With {.City = "Louisville"}
' --or--
Dim cust4 As New Customer("Toni Poe") With {.City = "Louisville"}
Du behöver inte initiera alla egenskaper, som följande kod visar.
Dim cust5 As Customer = New Customer With {.Name = "Toni Poe"}
Initieringslistan får dock inte vara tom. Uninitialiserade egenskaper behåller sina standardvärden.
Skriv slutsatsdragning med namngivna typer
Du kan förkorta koden för deklarationen av cust1
genom att kombinera objektinitierare och lokal typinferens. På så sätt kan du utelämna As
-satsen i variabeldeklarationen. Datatypen för variabeln härleds från den typ av objekt som skapas av tilldelningen. I följande exempel är Customer
typen av cust6
.
Dim cust6 = New Customer With {.Name = "Toni Poe",
.City = "Louisville"}
Kommentarer om namngivna typer
En klassmedlem kan inte initieras mer än en gång i objektinitierarens lista. Deklarationen av
cust7
orsakar ett fel.'' This code does not compile because Name is initialized twice. ' Dim cust7 = New Customer With {.Name = "Toni Poe", ' .City = "Louisville", ' .Name = "Blue Yonder Airlines"}
En medlem kan användas för att initiera sig själv eller ett annat fält. Om en medlem nås innan den har initierats, som i följande deklaration för
cust8
, används standardvärdet. Kom ihåg att när en deklaration som använder en objektinitierare bearbetas är det första som händer att rätt konstruktor anropas. Därefter initieras de enskilda fälten i initieringslistan. I följande exempel tilldelas standardvärdet förName
för ochcust8
ett initierat värde tilldelas icust9
.Dim cust8 = New Customer With {.Name = .Name & ", President"} Dim cust9 = New Customer With {.Name = "Toni Poe", .Title = .Name & ", President"}
I följande exempel används den parametriserade konstruktorn från
cust3
ochcust4
för att deklarera och initieracust10
ochcust11
.Dim cust10 = New Customer("Toni Poe") With {.Name = .Name & ", President"} ' --or-- Dim cust11 As New Customer("Toni Poe") With {.Name = .Name & ", President"}
Objektinitierare kan kapslas. I följande exempel
AddressClass
är en klass som har två egenskaper ochState
City
, ochCustomer
klassen har enAddress
egenskap som är en instans avAddressClass
.Dim cust12 = New Customer With {.Name = "Toni Poe", .Address = New AddressClass With {.City = "Louisville", .State = "Kentucky"}} Console.WriteLine(cust12.Address.State)
Initieringslistan får inte vara tom.
Instansen som initieras kan inte vara av typen Objekt.
Klassmedlemmar som initieras kan inte vara delade medlemmar, skrivskyddade medlemmar, konstanter eller metodanrop.
Klassmedlemmar som initieras kan inte indexeras eller kvalificeras. Följande exempel ger upphov till kompilatorfel:
'' Not valid.
' Dim c1 = New Customer With {.OrderNumbers(0) = 148662}
' Dim c2 = New Customer with {.Address.City = "Springfield"}
Anonyma typer
Anonyma typer använder objektinitierare för att skapa instanser av nya typer som du inte uttryckligen definierar och namnger. I stället genererar kompilatorn en typ enligt de egenskaper som du anger i objektinitierarens lista. Eftersom namnet på typen inte har angetts kallas det för en anonym typ. Jämför till exempel följande deklaration med den tidigare för cust6
.
Dim cust13 = New With {.Name = "Toni Poe",
.City = "Louisville"}
Den enda skillnaden syntaktiskt är att inget namn har angetts efter New
för datatypen. Men det som händer är helt annorlunda. Kompilatorn definierar en ny anonym typ som har två egenskaper och Name
City
, och skapar en instans av den med de angivna värdena. Typinferens avgör vilka typer av Name
och City
i exemplet som ska vara strängar.
Varning
Namnet på den anonyma typen genereras av kompilatorn och kan variera från kompilering till kompilering. Koden ska inte använda eller förlita sig på namnet på en anonym typ.
Eftersom namnet på typen inte är tillgängligt kan du inte använda en As
-sats för att deklarera cust13
. Dess typ måste härledas. Utan att använda sen bindning begränsar detta användningen av anonyma typer till lokala variabler.
Anonyma typer ger kritiskt stöd för LINQ-frågor. Mer information om användningen av anonyma typer i frågor finns i Anonyma typer och Introduktion till LINQ i Visual Basic.
Kommentarer om anonyma typer
Normalt är alla eller de flesta egenskaper i en anonym typdeklaration viktiga egenskaper, som anges genom att skriva nyckelordet
Key
framför egenskapsnamnet.Dim anonymousCust1 = New With {Key .Name = "Hugo Garcia", Key .City = "Louisville"}
Mer information om nyckelegenskaper finns i Nyckel.
Precis som namngivna typer måste initierarlistor för anonyma typdefinitioner deklarera minst en egenskap.
Dim anonymousCust = New With {.Name = "Hugo Garcia"}
När en instans av en anonym typ deklareras genererar kompilatorn en matchande definition av anonym typ. Namnen och datatyperna för egenskaperna hämtas från instansdeklarationen och inkluderas av kompilatorn i definitionen. Egenskaperna namnges inte och definieras i förväg, eftersom de skulle vara för en namngiven typ. Deras typer härleds. Du kan inte ange datatyperna för egenskaperna med hjälp av en
As
-sats.Anonyma typer kan också upprätta namn och värden för sina egenskaper på flera andra sätt. Till exempel kan en anonym typegenskap ta både namnet och värdet för en variabel, eller namnet och värdet för en egenskap för ett annat objekt.
' 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}
Mer information om alternativen för att definiera egenskaper i anonyma typer finns i Så här gör du: Härleda egenskapsnamn och typer i anonyma typdeklarationer.