속성(F#)
속성은 개체와 관련된 값을 나타내는 멤버입니다.
// 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 ]
설명
속성은 개체 지향 프로그래밍의 "포함" 관계를 나타냅니다. 이는 개체 인스턴스와 관련이 있는 데이터를 나타내거나 정적 속성인 경우 형식과 관련이 있는 데이터를 나타냅니다.
속성에 대 한 백업 저장소 라고도 하는 내부 값을 명시적으로 지정할 것인지 또는 사용자에 대 한 백업 저장소를 자동으로 생성 하도록 컴파일러를 허용 하려는 경우에 따라 두 가지 방법으로 속성을 선언할 수 있습니다.일반적으로 때 속성 값 또는 변수 단지 간단한 래퍼 속성에는 특수 구현이 있는 경우는 더 분명 하 게 하는 자동 방법은 사용 해야 합니다.속성을 명시적으로 선언할 수는 member 키워드.이 선언 구문 뒤에는 get 및 set 메서드와 명명된 접근자를 지정하는 구문이 옵니다.다양 한 형태의 명시적 구문 구문 섹션에 표시 되는 읽기/쓰기, 읽기 전용 및 쓰기 전용 속성에 대해 사용 됩니다.읽기 전용 속성에 대해서는 get 메서드만 정의하고, 쓰기 전용 속성에 대해서는 set 메서드만 정의합니다.속성에 get 및 set 접근자가 둘 다 있는 경우 다음 코드에서와 같이 대체 구문을 사용하여 각 접근자별로 서로 다른 특성 및 액세스 가능성 한정자를 지정할 수 있습니다.
// 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
get 및 set 메서드가 모두 있는 읽기/쓰기 속성의 경우 get 및 set의 순서를 바꿔도 상관이 없습니다.또는 조합된 구문을 사용하는 대신 get 전용으로 표시된 구문과 set 전용으로 표시된 구문을 따로따로 제공할 수도 있습니다.이렇게 하면 필요한 경우 get 메서드나 set 메서드를 개별적으로 쉽게 주석 처리하여 제외할 수 있습니다.다음 코드에서는 조합된 구문 대신 이 대체 방법을 사용하는 예를 보여 줍니다.
member this.MyReadWriteProperty with get () = myInternalValue
member this.MyReadWriteProperty with set (value) = myInternalValue <- value
속성의 데이터가 저장되는 개인 값을 백업 저장소라고 합니다.백업 저장소를 자동으로 만드는 컴파일러 키워드 사용 member valself-identifier를 생략 한 다음 속성을 초기화 하는 식을 제공 합니다.포함 속성은 변경할 수 있습니다 with get, set.예를 들어, 다음 클래스 형식을 자동으로 구현 된 두 개의 속성이 포함 되어 있습니다. Property1읽기 전용이 고 기본 생성자에 제공 된 인수를 초기화 하 고 Property2 설정할 수 있는 속성을 빈 문자열로 초기화 됩니다.
type MyClass(property1 : int) =
member val Property1 = property1
member val Property2 = "" with get, set
자동으로 구현 된 속성은 형식의 초기화 부분 들은 다른 멤버 정의 하기 전에 마찬가지로 포함 되어야 합니다 let 바인딩 및 do 바인딩 형식 정의 합니다.Note는 자동으로 구현 된 속성을 초기화 하는 식 및 않습니다 속성에 액세스할 때마다 초기화만 계산 됩니다.이 이와 대조적으로 명시적으로 구현 된 속성의 동작이입니다.이 효과적으로 이러한 속성을 초기화 하는 코드는 의미 하는 클래스의 생성자에 추가 됩니다.이러한 차이 보여 주는 다음 코드를 고려 하십시오.
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
Output
Explicitproperty는 호출 될 때마다 변경 되는 반면 값 AutoProperty 반복적으로 호출 될 때 변경 되지 위의 코드의 출력을 보여 줍니다.명시적 속성의 getter 메서드를 있는 그대로 될 때마다 자동으로 구현 된 속성에 대해 식을 계산 하지 않는다는 보여 줍니다.
주의 |
---|
속성의 초기화를 자동으로 작동 하지 않는 기본 클래스 생성자에 사용자 지정 작업을 수행할 Entity Framework (System.Data.Entity) 구현 등 일부 라이브러리입니다.이러한 경우 명시적 속성을 사용 하십시오. |
속성은 클래스, 구조체, 구별된 공용 구조체, 레코드, 인터페이스 및 형식 확장명의 멤버일 수 있으며, 개체 식에서 속성을 정의할 수도 있습니다.
속성에 특성을 적용할 수 있습니다.속성에 특성을 적용하려면 속성 앞에 별도의 줄을 사용하여 특성을 작성해야 합니다.자세한 내용은 특성(F#)을 참조하십시오.
기본적으로 속성은 공용입니다.속성에 액세스 가능성 한정자를 적용할 수도 있습니다.get 및 set 메서드 모두에 액세스 가능성 한정자를 적용하려면 속성 이름 바로 앞에 해당 한정자를 추가하고, 각 접근자별로 서로 다른 액세스 가능성을 지정하려면 get 및 set 키워드 앞에 해당 한정자를 추가합니다.accessibility-modifier는 public, private, internal 중 하나가 될 수 있습니다.자세한 내용은 액세스 제어(F#)를 참조하십시오.
속성에 액세스할 때마다 속성 구현이 실행됩니다.
정적 속성과 인스턴스 속성
속성은 정적 속성이거나 인스턴스 속성일 수 있습니다.정적 속성은 인스턴스 없이 호출할 수 있으며 개별 개체가 아니라 형식과 관련된 값에 사용됩니다.정적 속성에는 self-identifier를 생략 합니다.Self-identifier는 인스턴스 속성을 필수 요소입니다.
다음 예제에 나와 있는 정적 속성 정의는 속성의 백업 저장소인 정적 필드 myStaticValue가 있는 시나리오를 기반으로 합니다.
static member MyStaticProperty
with get() = myStaticValue
and set(value) = myStaticValue <- value
속성은 배열 형식일 수도 있습니다. 이 경우 해당 속성을 인덱싱된 속성이라고 합니다.자세한 내용은 인덱싱된 속성(F#)을 참조하십시오.
속성의 형식 주석
대부분의 경우 컴파일러에서 충분한 정보를 활용하여 백업 저장소의 형식으로부터 속성의 형식을 유추할 수 있지만, 형식 주석을 추가하여 형식을 명시적으로 설정할 수도 있습니다.
// 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
속성 set 접근자 사용
<- 연산자를 사용하여 set 접근자를 제공하는 속성을 설정할 수 있습니다.
// 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)
출력은 20입니다.
추상 속성
속성은 추상일 수 있습니다.메서드의 경우와 마찬가지로 여기서 추상은 속성과 관련된 가상 디스패치가 있다는 의미입니다.물론 추상 속성은 동일한 클래스에 정의가 포함되어 있지 않은 진정한 의미에서의 추상일 수도 있습니다.따라서 이러한 속성을 포함하는 클래스는 추상 클래스입니다.또는 속성이 가상이라는 데 추상의 의미가 있을 수도 있습니다. 이 경우에는 동일한 클래스에 정의가 있어야 합니다.추상 속성은 private이 아니어야 합니다. 접근자 중 하나가 추상이면 나머지 접근자도 모두 추상이어야 합니다.추상 클래스에 대한 자세한 내용은 추상 클래스(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