액세스 제어(F#)
액세스 제어란 클라이언트에서 사용할 수 있는 형식, 메서드, 함수 등의 특정 프로그램 요소를 선언하는 것을 말합니다.
액세스 제어 기본 사항
F#에서는 모듈, 형식, 메서드, 값 정의, 함수, 속성, 명시적 필드 등에 액세스 제어 지정자 public, internal 및 private을 적용할 수 있습니다.
public은 임의의 호출자를 통해 엔터티에 액세스할 수 있음을 의미합니다.
internal은 동일한 어셈블리에서만 엔터티에 액세스할 수 있음을 의미합니다.
private은 바깥쪽 형식이나 모듈에서만 엔터티에 액세스할 수 있음을 의미합니다.
참고
protected 액세스를 지원하는 언어로 작성된 형식을 사용하려는 경우 액세스 지정자 protected를 사용할 수 있기는 하지만 F#에서 이 액세스 지정자를 공식적으로 지원하지는 않습니다. 따라서 보호된 메서드를 재정의하는 경우 클래스 및 그 하위 항목 내에서만 메서드에 계속 액세스할 수 있습니다.
일반적으로 지정자는 엔터티 이름 앞에 옵니다. 단, mutable 또는 inline 지정자를 사용할 때는 예외여서 이들 지정자는 액세스 제어 지정자 뒤에 옵니다.
어떠한 액세스 지정자도 사용하지 않는 경우에는 기본 지정자인 public이 사용됩니다. 단, 형식에 let 바인딩이 있으면 해당 형식에 대해 항상 private이 사용됩니다.
F# 프로그램 요소에 대한 액세스를 제어하는 또 다른 메커니즘으로 F#의 시그니처를 사용할 수 있습니다. 액세스 제어에는 시그니처가 필요하지 않습니다. 자세한 내용은 서명(F#)를 참조하십시오.
액세스 제어 규칙
액세스 제어에는 다음과 같은 규칙이 적용됩니다.
inherit을 사용하여 클래스의 기본 클래스를 지정하는 상속 선언, 클래스에서 인터페이스를 구현하도록 지정하는 인터페이스 선언 및 추상 멤버에는 항상 바깥쪽 형식과 같은 수준의 액세스 권한이 부여됩니다. 따라서 이들 구문에 대해서는 액세스 제어 지정자를 사용할 수 없습니다.
구별된 공용 구조체의 개별 항목은 공용 구조체 형식과 다른 별도의 액세스 제어 한정자를 가질 수 없습니다.
레코드 형식의 개별 필드는 레코드 형식과 다른 별도의 액세스 제어 한정자를 가질 수 없습니다.
예제
다음 코드에서는 액세스 제어 지정자를 사용하는 방법을 보여 줍니다. 프로젝트에는 Module1.fs와 Module2.fs라는 두 개의 파일이 있습니다. 각 파일은 암시적 모듈입니다. 따라서 Module1과 Module2라는 두 개의 모듈이 있습니다. private 형식과 internal 형식은 Module1에 정의됩니다. Module2에서 private 형식에는 액세스할 수 없지만 internal 형식에는 액세스할 수 있습니다.
// Module1.fs
module Module1
// This type is not usable outside of this file
type private MyPrivateType() =
// x is private since this is an internal let binding
let x = 5
// X is private and does not appear in the QuickInfo window
// when viewing this type in the Visual Studio editor
member private this.X() = 10
member this.Z() = x * 100
type internal MyInternalType() =
let x = 5
member private this.X() = 10
member this.Z() = x * 100
// Top-level let bindings are public by default,
// so "private" and "internal" are needed here since a
// value cannot be more accessible than its type.
let private myPrivateObj = new MyPrivateType()
let internal myInternalObj = new MyInternalType()
// let bindings at the top level are public by default,
// so result1 and result2 are public.
let result1 = myPrivateObj.Z
let result2 = myInternalObj.Z
다음 코드에서는 Module1.fs로 만든 형식의 액세스 가능성을 테스트합니다.
// Module2.fs
module Module2
open Module1
// The following line is an error because private means
// that it cannot be accessed from another file or module
// let private myPrivateObj = new MyPrivateType()
let internal myInternalObj = new MyInternalType()
let result = myInternalObj.Z