`file` 수정자
file 수정자
file 수정자는 최상위 타입의 가시성을 그 선언이 들어 있는 파일 안으로 제한해요. 소스 생성기(source generator)가 생성한 타입에 file 수정자를 붙이는 경우가 가장 많죠. 파일-로컬 타입(file-local type)은 소스 생성기 입장에서 생성한 타입들끼리 이름이 충돌하지 않도록 우아하게 피해 가는 방법을 제공해요.
본문
file 수정자는 아래 예시처럼 파일-로컬 타입을 선언해 줘요.
file class HiddenWidget
{
// implementation
}
파일-로컬 타입 안에 중첩된 타입도 마찬가지로, 그 선언이 들어 있는 파일 안에서만 보여요. 같은 어셈블리의 다른 타입들은 파일-로컬 타입과 같은 이름을 쓸 수 있어요. 파일-로컬 타입은 선언이 들어 있는 파일 안에서만 보이기 때문에, 이렇게 해도 이름 충돌이 생기지 않아요.
파일-로컬 타입은 파일-로컬이 아닌 타입에 선언된 어떤 멤버의 반환 타입이나 매개 변수 타입이 될 수 없어요. 또 파일-로컬이 아닌 타입의 필드 멤버가 될 수도 없고요. 다만, 더 넓게 보이는 타입이 파일-로컬 인터페이스 타입을 암시적으로 구현할 수는 있어요. 그 타입은 파일-로컬 인터페이스를 명시적으로 구현할 수도 있지만, 명시적 구현은 같은 파일 안에서만 쓸 수 있어요.
다음 예시는 파일-로컬 타입을 사용해 작업(worker) 메서드를 제공하는 public 타입을 보여 줘요. 게다가 이 public 타입은 파일-로컬 인터페이스를 암시적으로 구현하기도 해요.
:::code language="csharp" source="./snippets/FileScoped.cs" id="FileScopedType":::
다른 소스 파일에서는 파일-로컬 타입과 같은 이름의 타입을 선언할 수 있어요. 파일-로컬 타입 자체는 보이지 않을 뿐이죠.
:::code language="csharp" source="./snippets/Program.cs" id="ShadowsFileScopedType":::
멤버 조회(member lookup)는 다른 파일에 선언된 파일-로컬이 아닌 타입보다, 같은 파일에 선언된 파일-로컬 타입을 우선해요. 이 규칙 덕분에 소스 생성기는 멤버 조회가 다른 타입 선언과 모호해지지 않고 파일-로컬 타입으로 해석된다는 사실에 의존할 수 있어요. 위 예시에서 File1.cs 안의 HiddenWidget을 사용한 모든 곳은 File1.cs에 선언된 파일-로컬 타입으로 해석돼요. File1.cs의 파일-로컬 선언이 File2.cs의 public 선언을 가리는 거예요.
C# 언어 사양
더 자세한 내용은 C# 언어 사양의 선언된 접근성(Declared accessibility)을 참고해요.