Compartilhar via


Propriedades (F#)

Propriedades são membros que representam os valores associados a um objeto.

// 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 ]

Comentários

Propriedades representam o "tem uma" relação na programação orientada a objeto, que representa os dados que está associados com instâncias de objetos ou propriedades estáticas, com o tipo.

Você pode declarar propriedades de duas maneiras, dependendo se você deseja especificar explicitamente o valor subjacente (também chamado de armazenamento de backup) para a propriedade ou se deseja permitir que o compilador gere automaticamente o armazenamento de backup para você. Geralmente, você deve usar a forma mais explícita se a propriedade tem uma implementação não trivial e forma automática quando a propriedade é apenas um invólucro simple para um valor ou variável. Para declarar explicitamente uma propriedade, use o member palavra-chave. A sintaxe declarativa é seguida pela sintaxe Especifica a get e set métodos, também denominados acessadores. As várias formas de sintaxe explícita mostrada na seção sintaxe são usadas para leitura/gravação, propriedades de somente leitura e somente gravação. Propriedades somente leitura, defina apenas um get método; propriedades somente gravação, definir apenas uma set método. Observe que, quando uma propriedade tem ambos get e set acessadores, a sintaxe alternativa permite especificar atributos e modificadores de acessibilidade são diferentes para cada acessador, conforme mostrado no código a seguir.

// 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

Propriedades de leitura/gravação, ter um get e set método, a ordem de get e set pode ser revertida. Como alternativa, você pode fornecer a sintaxe mostrada para get apenas e a sintaxe mostrada para set somente em vez de usar a sintaxe combinada. Isso facilita a comentar o indivíduo get ou set método, se isso é algo que talvez você precise fazer. Essa alternativa usando a sintaxe combinada é mostrada no código a seguir.

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

Private valores que mantenha dados para propriedades são chamados fazendo lojas. Para que o compilador cria automaticamente o armazenamento de backup, use as palavras-chave member val, omita o self-identifier e fornecer uma expressão para inicializar a propriedade. Se a propriedade é ser mutável, inclua with get, set. Por exemplo, o seguinte tipo de classe inclui duas propriedades implementadas automaticamente. Property1é somente leitura e é inicializada para o argumento fornecido para o construtor principal e Property2 é uma propriedade definível inicializada para uma seqüência vazia:

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

Propriedades implementadas automaticamente fazem parte da inicialização de um tipo, devem ser incluídos antes de quaisquer outras definições de membro, como let ligações e do ligações em uma definição de tipo. Observe que a expressão inicializa uma propriedade automaticamente implementada é avaliada somente na inicialização e não sempre que a propriedade for acessada. Esse comportamento é em contraste com o comportamento de uma propriedade implementada explicitamente. Isso efetivamente significa que o código para inicializar essas propriedades é adicionado ao construtor de uma classe. Considere o seguinte código mostra essa diferença:

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.AutoProperty = %d" class1.AutoProperty
printfn "class1.ExplicitProperty = %d" class1.ExplicitProperty
printfn "class1.ExplicitProperty = %d" class1.ExplicitProperty

Saída

  

A saída do código anterior mostra que o valor de AutoProperty é alterado quando chamado repetidamente, enquanto o ExplicitProperty alterações cada vez que for chamado. Demonstra que a expressão para uma propriedade automaticamente implementada não é avaliada cada vez, como é o método getter da propriedade explícita.

Aviso

Existem algumas bibliotecas, como o Entity Framework (System.Data.Entity) que executam operações personalizadas em construtores de classe base que não funcionam bem com a inicialização do automaticamente implementada propriedades.Nesses casos, tente usar propriedades explícitas.

Propriedades podem ser membros de classes, estruturas, uniões discriminadas, registros, interfaces e extensões de tipo e também podem ser definidas em expressões de objeto.

Atributos podem ser aplicados às propriedades. Para aplicar um atributo a uma propriedade, grave o atributo em uma linha separada antes da propriedade. Para mais informações, consulte Atributos (F#).

Por padrão, as propriedades são públicas. Modificadores de acessibilidade também podem ser aplicadas às propriedades. Para aplicar um modificador de acessibilidade, adicioná-lo imediatamente antes do nome da propriedade se deve aplicar a ambos os get e set métodos; adicioná-lo antes de get e set palavras-chave se acessibilidade diferente é necessária para cada acessador. The accessibility-modifier can be one of the following: public, private, internal. Para mais informações, consulte Controle de acesso (F#).

Implementações de propriedade são executadas cada vez que uma propriedade é acessada.

Estático e propriedades de instância

Propriedades podem ser estáticos ou propriedades da instância. Propriedades estáticas podem ser chamadas sem uma instância e são usadas para valores associados ao tipo, não com objetos individuais. Propriedades estáticas, omita o self-identifier. O self-identifier é necessária para as propriedades da instância.

A seguinte definição de propriedade estática baseia-se em um cenário no qual você tem um campo estático myStaticValue que é o armazenamento de backup para a propriedade.

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

Propriedades também podem ser semelhantes a matriz, caso em que eles são chamados de indexado propriedades. Para mais informações, consulte Propriedades indexadas (F#).

Anotação de tipo de propriedades

Em muitos casos, o compilador não tem informações suficientes para inferir o tipo de uma propriedade do tipo de armazenamento de backup, mas você pode definir explicitamente o tipo adicionando uma anotação de tipo.

// 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

Usando a propriedade definir acessadores

Você pode definir propriedades que fornecem set acessadores usando o <- operador.

// 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)

A saída é 20.

Propriedades abstratas

Propriedades podem ser abstract. Como com os métodos, abstrata apenas significa que há um despacho virtual associado com a propriedade. Propriedades abstratas podem ser verdadeiramente abstratas, isto é, sem uma definição na mesma classe. Portanto, a classe que contém essa propriedade é uma classe abstrata. Como alternativa, o resumo apenas pode significar que uma propriedade é virtual, e nesse caso, uma definição deve estar presente na mesma classe. Observe que propriedades abstract não pode ser privadas e se um acessador é abstrato, o outro também deve ser abstrato. Para obter mais informações sobre classes abstratas, consulte Classes abstratas (F#).

// 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

Consulte também

Referência

Métodos (F#)

Outros recursos

Membros (F#)