Megosztás a következőn keresztül:


about_Classes_Constructors

Rövid leírás

Ismerteti, hogyan definiálhat konstruktorokat a PowerShell-osztályokhoz.

Hosszú leírás

A konstruktorok lehetővé teszik az alapértelmezett értékek beállítását és az objektumlogika érvényesítését az osztály példányának létrehozásakor. A konstruktorok neve megegyezik az osztály nevével. A konstruktoroknak lehetnek paramétereik az új objektum adattagjainak inicializálásához.

A PowerShell-osztálykonstruktorok speciális metódusokként vannak definiálva az osztályon. Az alábbi kivételekkel ugyanúgy viselkednek, mint a PowerShell-osztály metódusai:

  • A konstruktorok nem rendelkeznek kimeneti típussal. Nem használhatják a kulcsszót return .
  • A konstruktoroknak mindig ugyanaz a neve, mint az osztálynak.
  • A konstruktorokat nem lehet közvetlenül meghívni. Csak egy példány létrehozásakor futnak.
  • A konstruktorok soha nem jelennek meg a parancsmag kimenetében Get-Member .

A PowerShell-osztály módszereiről további információt a about_Classes_Methods című témakörben talál.

Az osztály nulla vagy több konstruktort definiálhat. Ha nincs konstruktor definiálva, az osztály alapértelmezett paraméter nélküli konstruktort kap. Ez a konstruktor inicializálja az összes tagot az alapértelmezett értékükre. Az objektumtípusok és sztringek null értékeket kapnak. Konstruktor definiálásakor a rendszer nem hoz létre alapértelmezett paraméter nélküli konstruktort. Szükség esetén hozzon létre egy paraméter nélküli konstruktort.

Paraméter nélküli statikus konstruktort is definiálhat.

Syntax

Az osztálykonstruktorok a következő szintaxisokat használják:

A konstruktor alapértelmezett szintaxisa

<class-name> () [: base([<params>])] {
    <body>
}

Statikus konstruktor szintaxisa

static <class-name> () [: base([<params>])] {
    <body>
}

Paraméteres konstruktorszintaxis (egysoros)

<class-name> ([[<parameter-type>]$<parameter-name>[, [<parameter-type>]$<parameter-name>...]]) [: base([<params>])] {
    <body>
}

Paraméteres konstruktorszintaxis (többsoros)

<class-name> (
    [<parameter-type>]$<parameter-name>[,
    [<parameter-type>]$<parameter-name>...]
) [: base([<params>])] {
    <body>
}

Példák

1. példa – Osztály meghatározása az alapértelmezett konstruktorral

Az ExampleBook1 osztály nem definiál konstruktort. Ehelyett az automatikus alapértelmezett konstruktort használja.

class ExampleBook1 {
    [string]   $Name
    [string]   $Author
    [int]      $Pages
    [datetime] $PublishedOn
}

[ExampleBook1]::new()
Name Author Pages PublishedOn
---- ------ ----- -----------
                0 1/1/0001 12:00:00 AM

Feljegyzés

A Név ésszerző tulajdonságok alapértelmezett értéke az$null, hogy sztringekként vannak begépelve, ami hivatkozástípus. A többi tulajdonság a definiált típus alapértelmezett értékével rendelkezik, mivel értéktípus-tulajdonságok. A tulajdonságok alapértelmezett értékeiről további információt a about_Classes_Properties "Alapértelmezett tulajdonságértékek" című témakörben talál.

2. példa – Az alapértelmezett konstruktor felülírása

Az ExampleBook2 explicit módon határozza meg az alapértelmezett konstruktort, amely a PublishedOn értékét az aktuális dátumra, a Pages értékét pedig a következőre 1állítja.

class ExampleBook2 {
    [string]   $Name
    [string]   $Author
    [int]      $Pages
    [datetime] $PublishedOn

    ExampleBook2() {
        $this.PublishedOn = (Get-Date).Date
        $this.Pages       = 1
    }
}

[ExampleBook2]::new()
Name Author Pages PublishedOn
---- ------ ----- -----------
                1 11/1/2023 12:00:00 AM

3. példa – Konstruktor-túlterhelések meghatározása

Az ExampleBook3 osztály három konstruktor-túlterhelést határoz meg, amelyek lehetővé teszik a felhasználók számára az osztály egy példányának létrehozását egy kivonatolóból, minden tulajdonságérték átadásával, valamint a könyv és a szerző nevének átadásával. Az osztály nem határozza meg az alapértelmezett konstruktort.

class ExampleBook3 {
    [string]   $Name
    [string]   $Author
    [int]      $Pages
    [datetime] $PublishedOn

    ExampleBook3([hashtable]$Info) {
        switch ($Info.Keys) {
            'Name'        { $this.Name        = $Info.Name }
            'Author'      { $this.Author      = $Info.Author }
            'Pages'       { $this.Pages       = $Info.Pages }
            'PublishedOn' { $this.PublishedOn = $Info.PublishedOn }
        }
    }

    ExampleBook3(
        [string]   $Name,
        [string]   $Author,
        [int]      $Pages,
        [datetime] $PublishedOn
    ) {
        $this.Name        = $Name
        $this.Author      = $Author
        $this.Pages       = $Pages
        $this.PublishedOn = $PublishedOn
    }

    ExampleBook3([string]$Name, [string]$Author) {
        $this.Name   = $Name
        $this.Author = $Author
    }
}

[ExampleBook3]::new(@{
    Name        = 'The Hobbit'
    Author      = 'J.R.R. Tolkien'
    Pages       = 310
    PublishedOn = '1937-09-21'
})
[ExampleBook3]::new('The Hobbit', 'J.R.R. Tolkien', 310, '1937-09-21')
[ExampleBook3]::new('The Hobbit', 'J.R.R. Tolkien')
[ExampleBook3]::new()
Name       Author         Pages PublishedOn
----       ------         ----- -----------
The Hobbit J.R.R. Tolkien   310 9/21/1937 12:00:00 AM
The Hobbit J.R.R. Tolkien   310 9/21/1937 12:00:00 AM
The Hobbit J.R.R. Tolkien     0 1/1/0001 12:00:00 AM

MethodException:
Line |
  42 |  [ExampleBook3]::new()
     |  ~~~~~~~~~~~~~~~~~~~~~
     | Cannot find an overload for "new" and the argument count: "0".

Az alapértelmezett konstruktor meghívása metóduskivételt ad vissza. Az automatikus alapértelmezett konstruktor csak akkor van definiálva egy osztályhoz, ha az osztály nem definiál konstruktorokat. Mivel az ExampleBook3 több túlterhelést határoz meg, az alapértelmezett konstruktor nem lesz automatikusan hozzáadva az osztályhoz.

4. példa – Konstruktorok láncolása megosztott módszerrel

Ez a példa bemutatja, hogyan írhat újrahasználható megosztott kódot konstruktorok számára. A PowerShell-osztályok nem használhatnak konstruktorláncolást, ezért ez a példaosztály inkább egy metódust Init() határoz meg. A módszernek számos túlterhelése van. A kevesebb paraméterrel rendelkező túlterhelések explicitebb túlterheléseket neveznek a meghatározatlan paraméterek alapértelmezett értékeivel.

class ExampleBook4 {
    [string]   $Name
    [string]   $Author
    [datetime] $PublishedOn
    [int]      $Pages

    ExampleBook4() {
        $this.Init()
    }
    ExampleBook4([string]$Name) {
        $this.Init($Name)
    }
    ExampleBook4([string]$Name, [string]$Author) {
        $this.Init($Name, $Author)
    }
    ExampleBook4([string]$Name, [string]$Author, [datetime]$PublishedOn) {
        $this.Init($Name, $Author, $PublishedOn)
    }
    ExampleBook4(
      [string]$Name,
      [string]$Author,
      [datetime]$PublishedOn,
      [int]$Pages
    ) {
        $this.Init($Name, $Author, $PublishedOn, $Pages)
    }

    hidden Init() {
        $this.Init('Unknown')
    }
    hidden Init([string]$Name) {
        $this.Init($Name, 'Unknown')
    }
    hidden Init([string]$Name, [string]$Author) {
        $this.Init($Name, $Author, (Get-Date).Date)
    }
    hidden Init([string]$Name, [string]$Author, [datetime]$PublishedOn) {
        $this.Init($Name, $Author, $PublishedOn, 1)
    }
    hidden Init(
        [string]$Name,
        [string]$Author,
        [datetime]$PublishedOn,
        [int]$Pages
      ) {
        $this.Name        = $Name
        $this.Author      = $Author
        $this.PublishedOn = $PublishedOn
        $this.Pages       = $Pages
    }
}

[ExampleBook4]::new()
[ExampleBook4]::new('The Hobbit')
[ExampleBook4]::new('The Hobbit', 'J.R.R. Tolkien')
[ExampleBook4]::new('The Hobbit', 'J.R.R. Tolkien', (Get-Date '1937-9-21'))
[ExampleBook4]::new(
    'The Hobbit',
    'J.R.R. Tolkien',
    (Get-Date '1937-9-21'),
    310
)
Name       Author         PublishedOn           Pages
----       ------         -----------           -----
Unknown    Unknown        11/1/2023 12:00:00 AM     1
The Hobbit Unknown        11/1/2023 12:00:00 AM     1
The Hobbit J.R.R. Tolkien 11/1/2023 12:00:00 AM     1
The Hobbit J.R.R. Tolkien 9/21/1937 12:00:00 AM     1
The Hobbit J.R.R. Tolkien 9/21/1937 12:00:00 AM   310

5. példa – Származtatott osztálykonstruktorok

Az alábbi példák olyan osztályokat használnak, amelyek meghatározzák az alaposztály statikus, alapértelmezett és paraméteres konstruktorait, valamint az alaposztálytól öröklő származtatott osztályt.

class BaseExample {
    static [void] DefaultMessage([type]$Type) {
        Write-Verbose "[$($Type.Name)] default constructor"
    }

    static [void] StaticMessage([type]$Type) {
        Write-Verbose "[$($Type.Name)] static constructor"
    }

    static [void] ParamMessage([type]$Type, [object]$Value) {
        Write-Verbose "[$($Type.Name)] param constructor ($Value)"
    }

    static BaseExample() { [BaseExample]::StaticMessage([BaseExample])  }
    BaseExample()        { [BaseExample]::DefaultMessage([BaseExample]) }
    BaseExample($Value)  { [BaseExample]::ParamMessage([BaseExample], $Value) }
}

class DerivedExample : BaseExample {
    static DerivedExample() { [BaseExample]::StaticMessage([DerivedExample])  }
           DerivedExample() { [BaseExample]::DefaultMessage([DerivedExample]) }

    DerivedExample([int]$Number) : base($Number) {
        [BaseExample]::ParamMessage([DerivedExample], $Number)
    }
    DerivedExample([string]$String) {
        [BaseExample]::ParamMessage([DerivedExample], $String)
    }
}

Az alábbi blokk az alaposztály konstruktorainak meghívására szolgáló részletes üzenetküldést mutatja be. A statikus konstruktorüzenet csak az osztály első példányának létrehozásakor lesz kibocsátva.

PS> $VerbosePreference = 'Continue'
PS> $b = [BaseExample]::new()

VERBOSE: [BaseExample] static constructor
VERBOSE: [BaseExample] default constructor

PS> $b = [BaseExample]::new()

VERBOSE: [BaseExample] default constructor

PS> $b = [BaseExample]::new(1)

VERBOSE: [BaseExample] param constructor (1)

A következő blokk a származtatott osztálykonstruktorok új munkamenetben való meghívására szolgáló részletes üzenetküldést mutatja be. A származtatott osztálykonstruktor első meghívásakor a rendszer meghívja az alaposztály és a származtatott osztály statikus konstruktorát. Ezek a konstruktorok nem lesznek újra meghívva a munkamenetben. Az alaposztály konstruktorai mindig a származtatott osztály konstruktorai előtt futnak.

PS> $VerbosePreference = 'Continue'
PS> $c = [DerivedExample]::new()

VERBOSE: [BaseExample] static constructor
VERBOSE: [DerivedExample] static constructor
VERBOSE: [BaseExample] default constructor
VERBOSE: [DerivedExample] default constructor

PS> $c = [DerivedExample]::new()

VERBOSE: [BaseExample] default constructor
VERBOSE: [DerivedExample] default constructor

PS> $c = [DerivedExample]::new(1)

VERBOSE: [BaseExample] param constructor (1)
VERBOSE: [DerivedExample] param constructor (1)

PS> $c = [DerivedExample]::new('foo')

VERBOSE: [BaseExample] default constructor
VERBOSE: [DerivedExample] param constructor (foo)

Konstruktor futtatási sorrendje

Amikor egy osztály példányosít, egy vagy több konstruktor kódját végrehajtja.

Az olyan osztályok esetében, amelyek nem öröklődnek egy másik osztálytól, a sorrend a következő:

  1. Az osztály statikus konstruktora.
  2. Az osztály megfelelő konstruktor-túlterhelése.

Egy másik osztálytól öröklő származtatott osztályok esetében a sorrend a következő:

  1. Az alaposztály statikus konstruktora.
  2. A származtatott osztály statikus konstruktora.
  3. Ha a származtatott osztálykonstruktor kifejezetten alapkonstruktor-túlterhelést hív meg, akkor az az alaposztály konstruktorát futtatja. Ha nem hív meg kifejezetten alapkonstruktort, akkor az alaposztály alapértelmezett konstruktorát futtatja.
  4. A származtatott osztály megfelelő konstruktor-túlterhelése.

A statikus konstruktorok minden esetben csak egyszer futnak egy munkamenetben.

A konstruktor viselkedésére és sorrendjére példa: 5. példa.

Rejtett konstruktorok

Az osztály konstruktorait elrejtheti a kulcsszóval deklarálva hidden . A rejtett osztálykonstruktorok a következők:

  • Nem szerepel az osztály alapértelmezett kimenetében.
  • A parancsmag által Get-Member visszaadott osztálytagok listájában nem szerepel. A rejtett tulajdonságok Get-Membermegjelenítéséhez használja a Force paramétert.
  • Nem jelenik meg a tabulátorkizárásban vagy az IntelliSense-ben, kivéve, ha a befejezés a rejtett tulajdonságot meghatározó osztályban történik.
  • Az osztály nyilvános tagjai. Ezek elérhetők és módosíthatók. Egy tulajdonság elrejtése nem teszi privátsá. Csak az előző pontokban leírtak szerint rejti el a tulajdonságot.

Feljegyzés

Ha elrejt egy konstruktort, a beállítás el lesz távolítva az new() IntelliSense-ből és a befejezési eredményekből.

A kulcsszóval kapcsolatos további információkért lásd: hidden about_Hidden.

Statikus konstruktorok

A konstruktort az osztály példányai helyett az osztályhoz tartozóként definiálhatja úgy, hogy a konstruktort a static kulcsszóval deklarálja. Statikus osztálykonstruktorok:

  • Csak az osztály egy példányának első létrehozásakor hívja meg a munkamenetet.
  • Nem rendelkezhet paraméterekkel.
  • A változóval $this nem érhető el példánytulajdonságok vagy metódusok.

Konstruktorok származtatott osztályokhoz

Ha egy osztály örököl egy másik osztályt, a konstruktorok meghívhatnak egy konstruktort az alaposztályból a base kulcsszóval. Ha a származtatott osztály nem hív meg explicit módon konstruktort az alaposztályból, ehelyett az alaposztály alapértelmezett konstruktorát hívja meg.

Nem hibás alapkonstruktor meghívásához adja hozzá : base(<parameters>) a konstruktor paramétereit és a törzsblokkot.

class <derived-class> : <base-class> {
    <derived-class>(<derived-parameters>) : <base-class>(<base-parameters>) {
        # initialization code
    }
}

Alaposztály-konstruktort meghívó konstruktor definiálásakor a paraméterek a következő elemek bármelyikét tartalmazhatják:

  • A származtatott osztálykonstruktor bármely paraméterének változója.
  • Bármilyen statikus érték.
  • Bármely kifejezés, amely a paramétertípus értékének kiértékelése.

Egy származtatott osztály konstruktorainak példáját lásd az 5. példában.

Láncoló konstruktorok

A C#-tal ellentétben a PowerShell-osztálykonstruktorok nem használhatnak láncolást a : this(<parameters>) szintaxissal. A kódismétlések csökkentése érdekében használjon olyan rejtett Init() metódust, amely több túlterhelést is alkalmaz ugyanahhoz a hatáshoz. A 4 . példa egy ilyen mintát használó osztályt mutat be.

Példánytulajdonságok és metódusok hozzáadása az Update-TypeData használatával

A tulajdonságok és metódusok közvetlenül az osztálydefinícióban való deklarálásán túl a statikus konstruktor egy osztálypéldányának tulajdonságait is meghatározhatja a Update-TypeData parancsmag használatával.

Használja ezt a kódrészletet a minta kiindulópontjaként. Szükség szerint cserélje le a helyőrző szöveget szögletes zárójelekben.

class <class-name> {
    static [hashtable[]] $MemberDefinitions = @(
        @{
            Name       = '<member-name>'
            MemberType = '<member-type>'
            Value      = <member-definition>
        }
    )

    static <class-name>() {
        $TypeName = [<class-name>].Name
        foreach ($Definition in [<class-name>]::MemberDefinitions) {
            Update-TypeData -TypeName $TypeName @Definition
        }
    }
}

Tipp.

A Add-Member parancsmag tulajdonságokat és metódusokat adhat hozzá egy osztályhoz nem statikus konstruktorokban, de a parancsmag minden alkalommal fut, amikor a konstruktort meghívják. A Update-TypeData statikus konstruktor használata biztosítja, hogy a tagok osztályhoz való hozzáadásához használt kódnak csak egyszer kell futnia egy munkamenetben.

Csak akkor adjon hozzá tulajdonságokat az osztályhoz nem statikus konstruktorokban, ha nem határozhatók meg Update-TypeDatapéldául írásvédett tulajdonságokkal.

A példánymetelyek Update-TypeDatadefiniálásáról további információt a about_Classes_Methods című témakörben talál. A példánytulajdonságok meghatározásával Update-TypeDatakapcsolatos további információkért lásd: about_Classes_Properties.

Korlátozások

A PowerShell-osztály konstruktorai a következő korlátozásokkal rendelkeznek:

  • A konstruktorláncolás nincs implementálva.

    Megkerülő megoldás: Definiálja a rejtett Init() metódusokat, és hívja meg őket a konstruktorokból.

  • A konstruktorparaméterek nem használhatnak attribútumokat, beleértve az érvényesítési attribútumokat is.

    Megkerülő megoldás: A konstruktor törzsében lévő paraméterek hozzárendelése az érvényesítési attribútummal.

  • A konstruktorparaméterek nem definiálhatnak alapértelmezett értékeket. A paraméterek mindig kötelezőek.

    Megkerülő megoldás: Nincs.

  • Ha egy konstruktor túlterhelése rejtett, a konstruktor minden túlterhelése is rejtettként lesz kezelve.

    Megkerülő megoldás: Nincs.

Lásd még