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.
Cuidado |
---|
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