Udostępnij za pośrednictwem


Pola jawne: val — Słowo kluczowe

Słowo val kluczowe służy do deklarowania lokalizacji do przechowywania wartości w klasie lub typie struktury bez inicjowania. Lokalizacje magazynu zadeklarowane w ten sposób są nazywane jawnymi polami. Innym zastosowaniem słowa kluczowego val jest połączenie ze słowem kluczowym w member celu zadeklarowania automatycznie zaimplementowanej właściwości. Aby uzyskać więcej informacji na temat automatycznie zaimplementowanych właściwości, zobacz Właściwości.

Składnia

val [ mutable ] [ access-modifier ] field-name : type-name

Uwagi

Typowym sposobem definiowania pól w klasie lub typie struktury jest użycie let powiązania. Jednak let powiązania muszą być inicjowane jako część konstruktora klasy, który nie zawsze jest możliwy, niezbędny lub pożądany. Możesz użyć słowa kluczowego val , jeśli chcesz, aby pole było niezainicjowane.

Jawne pola mogą być statyczne lub niestatyczne. Modyfikator dostępu może mieć publicwartość , privatelub internal. Domyślnie jawne pola są publiczne. Różni się to od let powiązań w klasach, które są zawsze prywatne.

Atrybut DefaultValue jest wymagany dla jawnych pól w typach klas, które mają konstruktor podstawowy. Ten atrybut określa, że pole jest inicjowane do zera. Typ pola musi obsługiwać inicjowanie zerowe. Typ obsługuje inicjowanie zerowe, jeśli jest to jeden z następujących elementów:

  • Typ pierwotny, który ma wartość zero.
  • Typ, który obsługuje wartość null, jako wartość normalną, jako nietypową wartość lub jako reprezentację wartości. Obejmuje to klasy, krotki, rekordy, funkcje, interfejsy, typy referencyjne platformy .NET, unit typ i typy unii dyskryminowanej.
  • Typ wartości platformy .NET.
  • Struktura, której wszystkie pola obsługują domyślną wartość zero.

Na przykład niezmienne pole o nazwie someField ma pole zapasowe w skompilowanej reprezentacji platformy .NET o nazwie someField@i uzyskujesz dostęp do przechowywanej wartości przy użyciu właściwości o nazwie someField.

W przypadku pola modyfikowalnego skompilowana reprezentacja platformy .NET jest polem .NET.

Ostrzeżenie

Przestrzeń nazw System.ComponentModel programu .NET Framework zawiera atrybut o tej samej nazwie. Aby uzyskać informacje o tym atrybucie, zobacz DefaultValueAttribute.

Poniższy kod przedstawia użycie jawnych pól i, dla porównania, let powiązanie w klasie, która ma konstruktor podstawowy. Należy pamiętać, że letpole myInt1 -bound jest prywatne. letJeśli pole myInt1 -bound jest przywołyane z metody składowej, identyfikator this własny nie jest wymagany. Jednak jeśli odwołujesz się do jawnych pól myInt2 i myString, wymagany jest identyfikator własny.

type MyType() =
    let mutable myInt1 = 10
    [<DefaultValue>] val mutable myInt2 : int
    [<DefaultValue>] val mutable myString : string
    member this.SetValsAndPrint( i: int, str: string) =
       myInt1 <- i
       this.myInt2 <- i + 1
       this.myString <- str
       printfn "%d %d %s" myInt1 (this.myInt2) (this.myString)

let myObject = new MyType()
myObject.SetValsAndPrint(11, "abc")
// The following line is not allowed because let bindings are private.
// myObject.myInt1 <- 20
myObject.myInt2 <- 30
myObject.myString <- "def"

printfn "%d %s" (myObject.myInt2) (myObject.myString)

Wynik jest następujący:

11 12 abc
30 def

Poniższy kod przedstawia użycie jawnych pól w klasie, która nie ma konstruktora podstawowego. W takim przypadku DefaultValue atrybut nie jest wymagany, ale wszystkie pola muszą zostać zainicjowane w konstruktorach zdefiniowanych dla typu.

type MyClass =
    val a : int
    val b : int
    // The following version of the constructor is an error
    // because b is not initialized.
    // new (a0, b0) = { a = a0; }
    // The following version is acceptable because all fields are initialized.
    new(a0, b0) = { a = a0; b = b0; }

let myClassObj = new MyClass(35, 22)
printfn "%d %d" (myClassObj.a) (myClassObj.b)

Wynik to 35 22.

Poniższy kod przedstawia użycie jawnych pól w strukturze. Ponieważ struktura jest typem wartości, automatycznie ma konstruktor bez parametrów, który ustawia wartości pól na zero. W związku z tym DefaultValue atrybut nie jest wymagany.

type MyStruct =
    struct
        val mutable myInt : int
        val mutable myString : string
    end

let mutable myStructObj = new MyStruct()
myStructObj.myInt <- 11
myStructObj.myString <- "xyz"

printfn "%d %s" (myStructObj.myInt) (myStructObj.myString)

Wynik to 11 xyz.

Uważaj, jeśli zamierzasz zainicjować strukturę przy mutable użyciu pól bez mutable słowa kluczowego, przypisania będą działać na kopii struktury, która zostanie odrzucona bezpośrednio po przypisaniu. W związku z tym struktura nie ulegnie zmianie.

[<Struct>]
type Foo =
    val mutable bar: string
    member self.ChangeBar bar = self.bar <- bar
    new (bar) = {bar = bar}

let foo = Foo "1"
foo.ChangeBar "2" //make implicit copy of Foo, changes the copy, discards the copy, foo remains unchanged
printfn "%s" foo.bar //prints 1

let mutable foo' = Foo "1"
foo'.ChangeBar "2" //changes foo'
printfn "%s" foo'.bar //prints 2

Jawne pola nie są przeznaczone do rutynowego użycia. Ogólnie rzecz biorąc, jeśli to możliwe, należy użyć let powiązania w klasie zamiast jawnego pola. Jawne pola są przydatne w niektórych scenariuszach współdziałania, takich jak w przypadku konieczności zdefiniowania struktury, która będzie używana w wywołaniu platformy do natywnego interfejsu API lub w scenariuszach międzyoperacyjności modelu COM. Aby uzyskać więcej informacji, zobacz Funkcje zewnętrzne. Inną sytuacją, w której może być konieczne jawne pole, jest praca z generatorem kodu języka F#, który emituje klasy bez konstruktora podstawowego. Jawne pola są również przydatne w przypadku zmiennych statycznych wątków lub podobnych konstrukcji. Aby uzyskać więcej informacji, zobacz System.ThreadStaticAttribute.

Gdy słowa kluczowe member val są wyświetlane razem w definicji typu, jest to definicja automatycznie zaimplementowanej właściwości. Aby uzyskać więcej informacji, zobacz Właściwości.

Zobacz też