rksoftware

Visual Studio とか C# とかが好きです

C# 11 の新機能を確認「ファイル スコープ型」

C# 11 の新機能を確認しています。目次は次の記事です。
rksoftware.hatenablog.com

今回は 「 ファイルスコープ型 」。公式 Learn の記事は次です。
learn.microsoft.com

file という型修飾子が追加されました。アクセス修飾子とは書いてありませんが、アクセス修飾子と思っていいのでは? 定義されたファイル内でだけ参照できるようになります。型修飾子となっているのは、メンバーでは使えないからでしょうか。

■ 前提 C# では一つのファイルに複数の型を定義できる

意外と知られていない事実なのですが、 C# は一つのファイルに複数の型を定義できます。知っていてもコーディングルールで一つのファイルには一つの型しか定義してはならないというワールドにいる方もすくなくないのではないでしょうか?
つまりこのようなことができます。

class Class1 { }
class Class2 { }

デフォルトのアクセス範囲

C# ではデフォルトが internal なので、上のコードは次と同等です。

internal class Class1 { }
internal class Class2 { }

つまり同一アセンブリからのみ参照できます (一部例外がありますが、ここでは触れません) 。

■ file 型修飾子の確認

ということで、次の二つのソースコードファイルが同一アセンブリ内にある場合、すべて問題なく参照できます。

class Class1 { }
class Class2 { Class1 c1; }
class Class3 { void Method() => new Class1(); }
class Class4 : Class1 { }
class OtherFileClass { Class1 _c1; }

ここで Class1file を付けると、 Class3 を除いた Class2Class4OtherFileClass のコードがエラーになります。

file class Class1 { }
class Class2 { Class1 c1; }
class Class3 { void Method() => new Class1(); }
class Class4 : Class1 { }
class OtherFileClass { void Method() => new Class1(); }

エラーの内容

エラー CS9051 ファイル ローカル型 'Class1' は、ファイル ローカル型 'Class2' 以外のメンバーの署名として使用できません。
エラー CS9053 ファイル ローカル型 'Class1' は、ファイル ローカル型 'Class4' 以外の基本データ型として使用できません。
エラー CS0246 型または名前空間の名前 'Class1' が見つかりませんでした (using ディレクティブまたはアセンブリ参照が指定されていることを確認してください)

エラーの説明

  • file 型修飾子の型をメンバーとして保持できるのは同一ファイル内の file 型修飾子のクラスだけです。 Class2 は file 型修飾子が付いていないのでエラーになります。
  • file 型修飾子の型を継承元にできるのは同一ファイル内の file 型修飾子のクラスだけです。 Class4 は file 型修飾子が付いていないのでエラーになります。
  • file 型修飾子の型を使用できるのは同一ファイル内だけです。 OtherFileClass は別ファイルなのでエラーになります。

次のようなコードはエラーになりません

Class2Class4 に file 型修飾子を付け、 OtherFileClass を同一ファイルに移すとエラーがなくなります。

file class Class1 { }
file class Class2 { Class1 c1; }
class Class3 { void Method() => new Class1(); }
file class Class4 : Class1 { }
class OtherFileClass { void Method() => new Class1(); }

■ 使いこなしましょう

これは特に複数人でコードを書くときに非常に役立ちそうです。もう今日から導入しましょう!