Dela via


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 namedCustmåste en Customer klass som har en Name egenskap redan finnas och deklarationen skapar en instans av den klassen. För anonymousCustdefinierar 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 Customertypen 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ör Name för och cust8ett initierat värde tilldelas i cust9.

    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 och cust4 för att deklarera och initiera cust10 och cust11.

    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 och StateCity , och Customer klassen har en Address egenskap som är en instans av AddressClass.

    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 NameCity, 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.

Se även