Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
As propriedades são membros que representam valores associados a um objeto.
Sintaxe
// Property that has both get and set defined.
[ attributes ]
[ static ] member [accessibility-modifier] [self-identifier.]PropertyName
with [ attributes-for-get ] [accessibility-modifier] get() =
get-function-body
and [ attributes-for-set ] [accessibility-modifier] set parameter =
set-function-body
// Alternative syntax for a property that has get and set.
[ static ] member [accessibility-modifier-for-get] [self-identifier.]PropertyName
with [ attributes-for-get ] get() =
get-function-body
[ static ] member [accessibility-modifier-for-set] [self-identifier.]PropertyName
with [ attributes-for-set ] 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.
[ static ] member [accessibility-modifier] [self-identifier.]PropertyName
with [ attributes ] get() =
get-function-body
// Property that has set only.
[ static ] member [accessibility-modifier] [self-identifier.]PropertyName
with [ attributes ] set parameter =
set-function-body
// Automatically implemented properties.
[ attributes ]
[ static ] member val [accessibility-modifier] PropertyName = initialization-expression [ with get, set ]
Observações
As propriedades representam a relação "tem um" na programação orientada a objetos, representando dados associados a instâncias de objeto ou, para propriedades estáticas, com o tipo.
Você pode declarar propriedades de duas maneiras, dependendo se deseja especificar explicitamente o valor subjacente (também chamado de repositório de backup) para a propriedade ou se deseja permitir que o compilador gere automaticamente o repositório de backup para você. Em geral, você deve usar a maneira mais explícita se a propriedade tiver uma implementação não trivial e a maneira automática quando a propriedade for apenas um wrapper simples para um valor ou variável. Para declarar uma propriedade explicitamente, use a member palavra-chave. Essa sintaxe declarativa é seguida pela sintaxe que especifica os métodos e get os set métodos, também denominados acessadores. As várias formas da sintaxe explícita mostrada na seção de sintaxe são usadas para propriedades somente leitura/gravação, somente leitura e gravação. Para propriedades somente leitura, você define apenas um get método; para propriedades somente gravação, defina apenas um set método. Observe que quando uma propriedade tem ambos get e set acessadores, a sintaxe alternativa permite especificar atributos e modificadores de acessibilidade que 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
Para propriedades de leitura/gravação, que têm um método e get um set método, a ordem de get e set pode ser revertida. Como alternativa, você pode fornecer a sintaxe mostrada apenas para get e a sintaxe mostrada apenas em set vez de usar a sintaxe combinada. Fazer isso torna mais fácil comentar o indivíduo get ou set o método, se isso for algo que talvez seja necessário fazer. Essa alternativa para usar a sintaxe combinada é mostrada no código a seguir.
member this.MyReadWriteProperty with get () = myInternalValue
member this.MyReadWriteProperty with set (value) = myInternalValue <- value
Os valores privados que contêm os dados das propriedades são chamados de repositórios de backup. Para que o compilador crie o repositório de backup automaticamente, use as palavras-chave member val, omita o auto-identificador e forneça uma expressão para inicializar a propriedade. Se a propriedade for mutável, inclua with get, set. Por exemplo, o tipo de classe a seguir inclui duas propriedades implementadas automaticamente.
Property1 é somente leitura e é inicializado para o argumento fornecido para o construtor primário e Property2 é uma propriedade configurável inicializada para uma cadeia de caracteres vazia:
type MyClass(property1 : int) =
member val Property1 = property1
member val Property2 = "" with get, set
As propriedades implementadas automaticamente fazem parte da inicialização de um tipo, portanto, elas devem ser incluídas antes de qualquer outra definição de membro, assim como let associações e do associações em uma definição de tipo. Observe que a expressão que inicializa uma propriedade implementada automaticamente é avaliada somente após a inicialização e não toda vez que a propriedade é acessada. Esse comportamento contrasta com o comportamento de uma propriedade explicitamente implementada. O que isso significa efetivamente é que o código para inicializar essas propriedades é adicionado ao construtor de uma classe. Considere o código a seguir que 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.ExplicitProperty = %d{class1.ExplicitProperty}"
Saída
class1.AutoProperty = 1853799794
class1.AutoProperty = 1853799794
class1.ExplicitProperty = 978922705
class1.ExplicitProperty = 1131210765
A saída do código anterior mostra que o valor de AutoProperty é inalterado quando chamado repetidamente, enquanto as ExplicitProperty alterações sempre que ele é chamado. Isso demonstra que a expressão de uma propriedade implementada automaticamente não é avaliada a cada vez, assim como o método getter para a propriedade explícita.
Aviso
Há 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 de propriedades implementadas automaticamente. Nesses casos, tente usar propriedades explícitas.
As 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 a propriedades. Para aplicar um atributo a uma propriedade, escreva o atributo em uma linha separada antes da propriedade. Para obter mais informações, consulte Attributes.
Por padrão, as propriedades são públicas. Modificadores de acessibilidade também podem ser aplicados a propriedades. Para aplicar um modificador de acessibilidade, adicione-o imediatamente antes do nome da propriedade se ele for destinado a aplicar a ambos e get aos métodos; adicione-o set antes das palavras-chave e get das set palavras-chave se for necessária acessibilidade diferente para cada acessador. O modificador de acessibilidade pode ser um dos seguintes: public, , private. internal Para obter mais informações, consulte Controle de Acesso.
As implementações de propriedade são executadas sempre que uma propriedade é acessada.
Propriedades estáticas e de instância
As propriedades podem ser propriedades estáticas ou de instância. As propriedades estáticas podem ser invocadas sem uma instância e são usadas para valores associados ao tipo, não com objetos individuais. Para propriedades estáticas, omita o auto-identificador. O auto-identificador é necessário para propriedades de instância.
A definição de propriedade estática a seguir baseia-se em um cenário no qual você tem um campo myStaticValue estático que é o repositório de backup da propriedade.
static member MyStaticProperty
with get() = myStaticValue
and set(value) = myStaticValue <- value
As propriedades também podem ser semelhantes à matriz, caso em que são chamadas de propriedades indexadas. Para obter mais informações, consulte Propriedades Indexadas.
Anotação de tipo para propriedades
Em muitos casos, o compilador tem informações suficientes para inferir o tipo de uma propriedade do tipo do repositório de backup, mas você pode definir o tipo explicitamente 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 acessadores do conjunto de propriedades
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
As propriedades podem ser abstratas. Assim como acontece com os métodos, abstract significa apenas que há uma expedição virtual associada à propriedade. As propriedades abstratas podem ser verdadeiramente abstratas, ou seja, sem uma definição na mesma classe. A classe que contém essa propriedade é, portanto, uma classe abstrata. Como alternativa, abstrato pode significar apenas que uma propriedade é virtual e, nesse caso, uma definição deve estar presente na mesma classe. Observe que as propriedades abstratas não devem ser privadas e, se um acessador for abstrato, o outro também deverá ser abstrato. Para obter mais informações sobre classes abstratas, consulte Classes Abstratas.
// 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