다음을 통해 공유


속성(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 ]

설명

속성은 개체 지향 프로그래밍의 "has a" 관계를 나타내며, 개체 인스턴스와 연결된 데이터 또는 정적 속성의 경우 형식을 나타냅니다.

속성에 대한 기본 값(백업 저장소라고도 함)을 명시적으로 지정할지 또는 컴파일러가 자동으로 백업 저장소를 생성하도록 허용할지에 따라 두 가지 방법으로 속성을 선언할 수 있습니다. 일반적으로 속성에 사소한 구현이 없는 경우 보다 명시적인 방법과 속성이 값 또는 변수에 대한 단순한 래퍼일 때의 자동 방법을 사용해야 합니다. 속성을 명시적으로 선언하려면 키워드(keyword) 사용합니다 member . 이 선언적 구문 뒤에는 명명된 접근자 및 set 메서드를 get 지정하는 구문이 잇습니다. 구문 섹션에 표시된 다양한 형태의 명시적 구문은 읽기/쓰기, 읽기 전용 및 쓰기 전용 속성에 사용됩니다. 읽기 전용 속성의 경우 메서드만 get 정의합니다. 쓰기 전용 속성의 경우 메서드만 set 정의합니다. 속성에 접근자와 set 접근자가 모두 get 있는 경우 대체 구문을 사용하면 다음 코드와 같이 각 접근자에 대해 서로 다른 특성 및 접근성 한정자를 지정할 수 있습니다.

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

읽기/쓰기 속성의 경우 a get 와 메서드를 모두 포함하며 set 순서 getset 되돌릴 수 있습니다. 또는 결합된 구문을 사용하는 대신에만 표시된 get 구문과 표시된 구문을 set 제공할 수 있습니다. 이렇게 하면 개인 get 또는 set 메서드를 더 쉽게 주석으로 처리할 수 있습니다. 결합된 구문을 사용하는 이 대안은 다음 코드에 나와 있습니다.

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

속성에 대한 데이터를 보유하는 개인 값을 백업 저장소라고 합니다. 컴파일러가 백업 저장소를 자동으로 만들도록 하려면 키워드(keyword) member val사용하고, 자체 식별자를 생략한 다음, 식을 제공하여 속성을 초기화합니다. 속성을 변경할 수 있는 경우 다음을 포함합니다 with get, set. 예를 들어 다음 클래스 형식에는 자동으로 구현된 두 가지 속성이 포함됩니다. Property1 는 읽기 전용이며 기본 생성자에 제공된 인수로 초기화되며 Property2 빈 문자열로 초기화된 settable 속성입니다.

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

자동으로 구현된 속성은 형식 초기화의 일부이므로 형식 정의의 바인딩 및 바인딩과 do 마찬가지로 let 다른 멤버 정의 앞에 포함되어야 합니다. 자동으로 구현된 속성을 초기화하는 식은 초기화 시만 평가되며 속성에 액세스할 때마다 평가되지 않습니다. 이 동작은 명시적으로 구현된 속성의 동작과는 대조적입니다. 이것이 효과적으로 의미하는 바는 이러한 속성을 초기화하는 코드가 클래스의 생성자에 추가된다는 것입니다. 이 차이를 보여 주는 다음 코드를 고려합니다.

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}"

출력

class1.AutoProperty = 1853799794
class1.AutoProperty = 1853799794
class1.ExplicitProperty = 978922705
class1.ExplicitProperty = 1131210765

앞의 코드의 출력은 AutoProperty 값이 반복적으로 호출될 때 변경되지 않은 반면 ExplicitProperty는 호출될 때마다 변경됨을 보여 주는 것입니다. 이는 명시적 속성에 대한 getter 메서드와 마찬가지로 자동으로 구현된 속성에 대한 식이 매번 평가되지 않음을 보여 줍니다.

Warning

자동으로 구현된 속성의 초기화와 잘 작동하지 않는 기본 클래스 생성자에서 사용자 지정 작업을 수행하는 Entity Framework(System.Data.Entity)와 같은 일부 라이브러리가 있습니다. 이러한 경우 명시적 속성을 사용해 보세요.

속성은 클래스, 구조체, 구분된 공용 구조체, 레코드, 인터페이스 및 형식 확장의 멤버일 수 있으며 개체 식에서도 정의할 수 있습니다.

속성에 특성을 적용할 수 있습니다. 속성에 특성을 적용하려면 속성 앞에 별도의 줄에 특성을 씁니다. 자세한 내용은 특성을 참조하세요.

기본적으로 속성은 public입니다. 접근성 한정자를 속성에 적용할 수도 있습니다. 접근성 한정자를 적용하려면 속성 이름과 메서드 모두 get 에 적용하려는 경우 속성 이름 바로 앞에 추가합니다set. 각 접근자에 대해 다른 접근성이 필요한 경우 키워드(keyword) 앞에 추가 getset 합니다. 접근성 한정자는 다음 publicprivateinternal중 하나일 수 있습니다. 자세한 내용은 Access Control을 참조하세요.

속성 구현은 속성에 액세스할 때마다 실행됩니다.

정적 및 인스턴스 속성

속성은 정적 또는 인스턴스 속성일 수 있습니다. 정적 속성은 인스턴스 없이 호출할 수 있으며 개별 개체가 아닌 형식과 연결된 값에 사용됩니다. 정적 속성의 경우 자체 식별자를 생략합니다. 인스턴스 속성에는 자체 식별자가 필요합니다.

다음 정적 속성 정의는 속성의 백업 저장소인 정적 필드 myStaticValue 가 있는 시나리오를 기반으로 합니다.

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

속성은 배열과 유사할 수도 있습니다. 이 경우 인덱싱된 속성이라고 합니다. 자세한 내용은 인덱싱된 속성을 참조 하세요.

속성에 대한 형식 주석

대부분의 경우 컴파일러에는 백업 저장소의 형식에서 속성 형식을 유추하기에 충분한 정보가 있지만 형식 주석을 추가하여 형식을 명시적으로 설정할 수 있습니다.

// 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 속성을 설정할 수 있습니다.

// 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입니다.

추상 속성

속성은 추상적일 수 있습니다. 메서드 abstract 와 마찬가지로 속성과 연결된 가상 디스패치가 있음을 의미합니다. 추상 속성은 진정한 추상 속성이 될 수 있습니다. 즉, 동일한 클래스의 정의가 없습니다. 따라서 이러한 속성을 포함하는 클래스는 추상 클래스입니다. 또는 추상은 속성이 가상임을 의미할 수 있으며, 이 경우 정의가 동일한 클래스에 있어야 합니다. 추상 속성은 private이 아니어야 하며 한 접근자가 추상인 경우 다른 접근자도 추상이어야 합니다. 추상 클래스에 대한 자세한 내용은 추상 클래스를 참조 하세요.

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

참고 항목