Vlastnosti (F#)

Vlastnosti jsou členy, které představují hodnoty přidružené k objektu.

Syntaxe

// Property that has both get and set defined.
[ attributes ]
[ static ] member [accessibility-modifier] [self-identifier.]PropertyName
with [accessibility-modifier] get() =
    get-function-body
and [accessibility-modifier] set parameter =
    set-function-body

// Alternative syntax for a property that has get and set.
[ attributes-for-get ]
[ static ] member [accessibility-modifier-for-get] [self-identifier.]PropertyName =
    get-function-body
[ attributes-for-set ]
[ static ] member [accessibility-modifier-for-set] [self-identifier.]PropertyName
with set parameter =
    set-function-body

// Property that has get only.
[ attributes ]
[ static ] member [accessibility-modifier] [self-identifier.]PropertyName =
    get-function-body

// Alternative syntax for property that has get only.
[ attributes ]
[ static ] member [accessibility-modifier] [self-identifier.]PropertyName
with get() =
    get-function-body

// Property that has set only.
[ attributes ]
[ static ] member [accessibility-modifier] [self-identifier.]PropertyName
with set parameter =
    set-function-body

// Automatically implemented properties.
[ attributes ]
[ static ] member val [accessibility-modifier] PropertyName = initialization-expression [ with get, set ]

Poznámky

Vlastnosti představují relaci "má" v objektově orientovaném programování, představující data přidružená k instancím objektů nebo pro statické vlastnosti typu.

Vlastnosti můžete deklarovat dvěma způsoby, a to v závislosti na tom, jestli chcete explicitně zadat podkladovou hodnotu (označovanou také jako záložní úložiště) pro vlastnost, nebo pokud chcete kompilátoru povolit automatické vygenerování záložního úložiště za vás. Obecně byste měli použít explicitnější způsob, pokud vlastnost má ne triviální implementaci a automatický způsob, když je vlastnost pouze jednoduchý obálka pro hodnotu nebo proměnnou. Chcete-li deklarovat vlastnost explicitně, použijte member klíčové slovo. Za touto deklarativní syntaxí následuje syntaxe, která určuje get metody a set také pojmenované přístupové objekty. Různé formy explicitní syntaxe uvedené v oddílu syntaxe se používají pro vlastnosti jen pro čtení a zápis, jen pro čtení a zápis. U vlastností jen pro čtení definujete pouze metodu get . Pro vlastnosti jen pro zápis definujte pouze metodu set . Všimněte si, že pokud vlastnost má obě get a set přístupové objekty, alternativní syntaxe umožňuje zadat atributy a modifikátory přístupnosti, které se pro každý přístup liší, jak je znázorněno v následujícím kódu.

// A read-only property.
member this.MyReadOnlyProperty = myInternalValue
// A write-only property.
member this.MyWriteOnlyProperty with set (value) = myInternalValue <- value
// A read-write property.
member this.MyReadWriteProperty
    with get () = myInternalValue
    and set (value) = myInternalValue <- value

U vlastností pro čtení a zápis, které mají jak metodu getset , pořadí get a set lze obrátit. Alternativně můžete zadat pouze syntaxi get a syntaxi zobrazenou pouze pro set použití kombinované syntaxe. Tímto způsobem můžete usnadnit zakomentování jednotlivé osoby get nebo set metody, pokud je to něco, co byste možná potřebovali udělat. Tato alternativa k použití kombinované syntaxe se zobrazí v následujícím kódu.

member this.MyReadWriteProperty with get () = myInternalValue
member this.MyReadWriteProperty with set (value) = myInternalValue <- value

Privátní hodnoty, které obsahují data pro vlastnosti, se nazývají záložní úložiště. Chcete-li, aby kompilátor vytvořil záložní úložiště automaticky, použijte klíčová slova member val, vynecháte identifikátor sebe-identifikátor a pak zadejte výraz pro inicializaci vlastnosti. Pokud má být vlastnost proměnlivá, zahrňte with get, set. Například následující typ třídy obsahuje dvě automaticky implementované vlastnosti. Property1 je jen pro čtení a inicializuje se do argumentu poskytnutého primárnímu konstruktoru a Property2 je nastavená vlastnost inicializovaná na prázdný řetězec:

type MyClass(property1 : int) =
member val Property1 = property1
member val Property2 = "" with get, set

Automaticky implementované vlastnosti jsou součástí inicializace typu, takže musí být zahrnuty před všemi dalšími definicemi členů, stejně jako let vazby a do vazby v definici typu. Všimněte si, že výraz, který inicializuje automaticky implementovanou vlastnost, se vyhodnotí pouze při inicializaci, a ne při každém přístupu k vlastnosti. Toto chování je na rozdíl od chování explicitně implementované vlastnosti. To znamená, že kód pro inicializaci těchto vlastností se přidá do konstruktoru třídy. Podívejte se na následující kód, který ukazuje tento rozdíl:

type MyClass() =
    let random  = new System.Random()
    member val AutoProperty = random.Next() with get, set
    member this.ExplicitProperty = random.Next()

let class1 = new MyClass()

printfn $"class1.AutoProperty = %d{class1.AutoProperty}"
printfn $"class1.ExplicitProperty = %d{class1.ExplicitProperty}"

Výstup

class1.AutoProperty = 1853799794
class1.AutoProperty = 1853799794
class1.ExplicitProperty = 978922705
class1.ExplicitProperty = 1131210765

Výstup předchozího kódu ukazuje, že hodnota AutoProperty je při opakovaném vyvolání nezměněna, zatímco ExplicitProperty se změní pokaždé, když je volána. To ukazuje, že výraz pro automaticky implementovanou vlastnost není vyhodnocen pokaždé, stejně jako getter metoda pro explicitní vlastnost.

Upozorňující

Existují některé knihovny, například Entity Framework (System.Data.Entity), které provádějí vlastní operace v konstruktorech základní třídy, které nefungují dobře s inicializací automaticky implementovaných vlastností. V těchto případech zkuste použít explicitní vlastnosti.

Vlastnosti mohou být členy tříd, struktur, diskriminovaných sjednocení, záznamů, rozhraní a rozšíření typů a lze je také definovat ve výrazech objektů.

Atributy lze použít u vlastností. Chcete-li použít atribut na vlastnost, napište atribut na samostatný řádek před vlastnost. Další informace naleznete v tématu Atributy.

Ve výchozím nastavení jsou vlastnosti veřejné. Modifikátory přístupnosti lze také použít u vlastností. Pokud chcete použít modifikátor přístupnosti, přidejte ho bezprostředně před název vlastnosti, pokud se má použít pro obě get metody a set metody; přidejte ho před get a set klíčová slova, pokud je pro každého přístupového objektu vyžadována jiná přístupnost. Modifikátor přístupnosti může být jeden z následujících: public, private, internal. Další informace najdete v článku Access Control.

Implementace vlastností se provádějí při každém přístupu k vlastnosti.

Statické vlastnosti a vlastnosti instance

Vlastnosti mohou být statické nebo vlastnosti instance. Statické vlastnosti lze vyvolat bez instance a jsou použity pro hodnoty přidružené k typu, ne s jednotlivými objekty. U statických vlastností vynecháte identifikátor sebe sama. Pro vlastnosti instance se vyžaduje identifikátor sebe sama.

Následující definice statické vlastnosti je založená na scénáři, ve kterém máte statické pole myStaticValue , které je záložním úložištěm vlastnosti.

static member MyStaticProperty
    with get() = myStaticValue
    and set(value) = myStaticValue <- value

Vlastnosti můžou být také podobné poli, v takovém případě se označují jako indexované vlastnosti. Další informace naleznete v tématu Indexované vlastnosti.

Typ poznámky pro vlastnosti

V mnoha případech má kompilátor dostatek informací k odvození typu vlastnosti z typu záložního úložiště, ale typ můžete nastavit explicitně přidáním poznámky k typu.

// To apply a type annotation to a property that does not have an explicit
// get or set, apply the type annotation directly to the property.
member this.MyProperty1 : int = myInternalValue
// If there is a get or set, apply the type annotation to the get or set method.
member this.MyProperty2 with get() : int = myInternalValue

Použití přístupových objektů sady vlastností

Pomocí operátoru <- můžete nastavit vlastnosti, které poskytují set přístupové objekty.

// Assume that the constructor argument sets the initial value of the
// internal backing store.
let mutable myObject = new MyType(10)
myObject.MyProperty <- 20
printfn "%d" (myObject.MyProperty)

Výstup je 20.

Abstraktní vlastnosti

Vlastnosti mohou být abstraktní. Stejně jako u metod to znamená, abstract že k vlastnosti je přidruženo virtuální odeslání. Abstraktní vlastnosti mohou být skutečně abstraktní, tj. bez definice ve stejné třídě. Třída, která obsahuje takovou vlastnost, je tedy abstraktní třída. Abstraktní může také znamenat, že vlastnost je virtuální a v takovém případě musí být definice přítomna ve stejné třídě. Všimněte si, že abstraktní vlastnosti nesmí být soukromé a pokud je jeden přístup abstraktní, druhý musí být také abstraktní. Další informace o abstraktních třídách naleznete v tématu Abstraktní třídy.

// Abstract property in abstract class.
// The property is an int type that has a get and
// set method
[<AbstractClass>]
type AbstractBase() =
    abstract Property1: int with get, set

// Implementation of the abstract property
type Derived1() =
    inherit AbstractBase()
    let mutable value = 10

    override this.Property1
        with get () = value
        and set (v: int) = value <- v

// A type with a "virtual" property.
type Base1() =
    let mutable value = 10
    abstract Property1: int with get, set

    default this.Property1
        with get () = value
        and set (v: int) = value <- v

// A derived type that overrides the virtual property
type Derived2() =
    inherit Base1()
    let mutable value2 = 11

    override this.Property1
        with get () = value2
        and set (v) = value2 <- v

Viz také