Compartilhar via


Campos explícitos: a palavra-chave val (F#)

A palavra-chave de val é usada para declarar um campo em um tipo de classe ou estrutura sem inicializá-la. Os campos são declarados assim chamados campos explícito. Outro uso da palavra-chave de val é em conjunto com a palavra-chave de member para declarar uma propriedade automática implementado. Para obter mais informações sobre propriedades autoimplementadas, consulte Propriedades (F#).

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

Comentários

A maneira comum de definir campos em um tipo de classe ou estrutura é usar associação de let . Em o entanto, as associações de let devem ser inicializadas como parte do construtor da classe, que não é sempre possível, necessário, ou desejável. Você pode usar a palavra-chave de val quando você desejar um campo que é não inicializado.

Os campos podem ser explícitos estáticos ou não-estáticos. access-modifier pode ser public, private, ou internal. Por padrão, os campos explícitos são públicos. Isso difere de associações de let classes, que são sempre particulares.

O atributo de Valor padrão é necessário em campos [icitos nos tipos de classe que tem um construtor primária. Este atributo especifica que o campo é inicializado para zero. O tipo de campo deve oferecer suporte a zero inicialização. Um tipo oferece suporte a zero inicialização se é um dos seguintes:

  • Um tipo primitivo que tem um valor nulo.

  • Um tipo que suporta um valor nulo, como um valor comum, como um valor anormal, ou como uma representação de um valor. Isso inclui classes, tuples, registros, funções, interfaces, tipos de referência .NET, o tipo de unit , e tipos discriminados de união.

  • Um tipo de valor .NET.

  • Campos de uma estrutura cujos todo o suporte um valor padrão zero.

Aviso

Observação O namespace System.ComponentModel do .NET Framework contém um atributo que tem o mesmo nome.Para obter informações sobre esse atributo, consulte DefaultValueAttribute.

O código a seguir mostra o uso de campos explícita e, para comparação, que let de associação em uma classe que tem um construtor primária. Observe que let- o campo associado é myInt1 particular. Quando let- o campo associado é referenciado myInt1 de um método do membro, auto que o identificador this não é necessário. Mas quando você está referenciando os campos explícitos myInt2 e myString, o identificador de auto é necessário.

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)

A saída é a seguinte:

11 12 abc

30 def

O código a seguir mostra o uso de campos [icitos em uma classe que não tem um construtor primária. Em esse caso, o atributo de DefaultValue não é necessário, mas todos os campos deve ser inicializada nos construtores que são definidos para o tipo.

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)

A saída é 35 22.

O código a seguir mostra o uso de campos [icitos em uma estrutura. Porque uma estrutura é um tipo de valor, automaticamente tem um construtor padrão que define os valores dos campos em zero. Portanto, o atributo de DefaultValue não é necessário.

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)

A saída é 11 xyz.

Os campos explícitos não são destinados ao uso atual. Em geral, quando possível você deve usar let que associa em uma classe em vez de um campo explícito. Os campos explícitos são úteis em determinados cenários de interoperabilidade, como quando você precisa definir uma estrutura que é usada em uma chamada de invocação de plataforma a API nativo, ou em cenários de interoperabilidade COM. Para mais informações, consulte Funções externas (F#). Outra situação em que um campo explícito pode ser necessário é quando você está trabalhando com um gerador de código de F# que emite classes sem um construtor primária. Os campos explícitos também são úteis para variáveis de com estático ou compilações semelhantes. Para mais informações, consulte ThreadStaticAttribute.

Quando as palavras-chave member val aparecem juntos em uma definição de tipo, é uma definição de uma propriedade automaticamente implementado. Para mais informações, consulte Propriedades (F#).

Consulte também

Referência

Propriedades (F#)

Associações let em classes (F#)

Outros recursos

Membros (F#)