C# コンパイラ エラー CS0059:アクセシビリティ不整合の原因と対策について解説
CS0059はC#のコンパイルエラーの一つです。
エラーはデリゲートやメソッドで使用するパラメーター型のアクセス修飾子が、宣言側より低く設定されている場合に表示されます。
この場合、たとえばpublicなデリゲートでprivateな型を使っている可能性があるため、各型のアクセスレベルを統一することで解決いただけます。
エラーCS0059の発生原因
アクセシビリティ不一致の概念
CS0059 エラーは、デリゲートのパラメーター型や戻り値の型のアクセスレベルが、デリゲート自体より低い場合に発生します。
例えば、public
として定義されたデリゲートのパラメーターに、デフォルト(privateやinternal)の型を指定すると、エラーが発生する可能性があります。
この場合、デリゲート全体が参照可能なアクセスレベルに、すべての型を合わせる必要があるというルールが働いています。
デリゲートとパラメーター型のアクセスレベルの違い
delegate
が public
として定義されている場合、そのパラメーター型も同様に public
でなければなりません。
アクセスレベルが低い型を使用すると、デリゲートの利用者が型の詳細を知ることができず、コンパイルエラー CS0059 が発生します。
この不一致は、コンパイラが型の一貫性を保つために求めるセキュリティルールの一環です。
型定義時のアクセス修飾子の設定状況
型(クラス、構造体、インターフェイス)のアクセス修飾子は明示的に指定しない場合、デフォルトのアクセスレベルとなります。
たとえば、外部に公開することを意図していない型は private
になりがちです。
一方で、それを参照する public
のメソッドや delegate は、アクセスレベルの不整合が原因でエラーを引き起こす可能性があるため、定義時に正しい修飾子を付与する必要があります。
コード例で見る発生状況
エラーを引き起こす不適切なコード例
誤ったアクセス修飾子の適用例
以下のサンプルコードは、アクセス修飾子の設定が不適切なために CS0059 エラーが発生する例です。
// CS0059_Error.cs
// クラスのアクセス修飾子を指定しないため、デフォルトで internal(または private)の場合がある
class MyClass // クラスを外部に公開する場合は public に変更する必要がある
{
// サンプルのためのフィールド
string message = "内部メッセージ";
}
// public な delegate に対し、アクセスレベルが低い型をパラメーターとして使用している
public delegate void MyClassDelegate(MyClass myClass);
public class Program
{
public static void Main()
{
// 初期化処理はここでは省略
System.Console.WriteLine("CS0059 エラー発生のサンプル");
}
}
// コンパイラエラーの例(実際の出力は環境により異なります)
// エラー CS0059: アクセシビリティに一貫性がありません。パラメーター型 'MyClass' のアクセス修飾子はデリゲート 'MyClassDelegate' よりも低いです。
正常なコード例との比較
以下のサンプルコードは、MyClass
に public
アクセス修飾子を付与して、デリゲートが参照する型のアクセスレベルを整えた例です。
// CS0059_Fixed.cs
// クラスを public にすることで、外部からの参照を可能にする
public class MyClass // 修正済み
{
// サンプルのためのフィールド
string message = "内部メッセージ";
}
public delegate void MyClassDelegate(MyClass myClass);
public class Program
{
public static void Main()
{
// MyClass のインスタンスを生成した上で delegate を初期化する例
MyClass instance = new MyClass();
MyClassDelegate handler = new MyClassDelegate(ShowMessage);
handler(instance);
}
// delegate に対応するメソッド
public static void ShowMessage(MyClass myClass)
{
System.Console.WriteLine("CS0059 エラーは解消されました。");
}
}
CS0059 エラーは解消されました。
アクセシビリティの基本知識
アクセス修飾子の種類と役割
C# では、主に以下の3種類のアクセス修飾子が存在します。
public
: どこからでもアクセス可能なため、外部ライブラリやアプリケーション間で使用される型やメソッドに使用されます。private
: 当該クラス内からのみアクセス可能なため、内部実装の隠蔽に利用されます。internal
: 同一アセンブリ内でのみアクセス可能なため、ライブラリ内部での実装詳細を隠すのに役立ちます。
これらの修飾子を適切に利用することで、プログラム全体のアクセス制御を明確にし、意図しない参照や操作を防ぐことができます。
public、private、internalの特性
public
は一貫性のある公開 API を構築する際に必要ですが、不要に公開することはセキュリティ上のリスクとなる場合があるため注意が必要です。private
はクラス内部でのみ利用され、外部からの不正なアクセスを防ぐための基本な手段です。internal
はアセンブリ内に限定されるため、他のアセンブリから参照される場面では、アクセスレベルが不足しエラーになる可能性があります。
それぞれのアクセスレベルには設計上の意味があり、正しい使い分けが求められます。
型とメソッド間のアクセスレベルの規則
メソッドの戻り値やパラメーターで参照する型は、メソッド自体と同じか、それ以上のアクセスレベルでなければなりません。
例えば、public
なメソッドに対してアクセスレベルが private
の型を使用すると、呼び出し側がその型を認識できず、エラーが発生します。
この規則は、コードの可読性と安全性を保つために設けられており、アクセス修飾子の整合性が重要なポイントとなります。
エラー解消の対策
アクセス修飾子の正しい設定方法
修正手順と注意点
エラー CS0059 を解消するためには、以下の手順が効果的です。
- 問題の delegate やメソッドのパラメーター、戻り値で参照される型のアクセス修飾子を確認します。
- 参照先の型のアクセスレベルを、delegate やメソッドと同じか、より高いレベルに変更します。
- クラスや構造体の定義において、明示的に
public
やinternal
を設定し、デフォルトアクセスレベルによる不整合を防ぎます。
修正する際は、アプリケーション全体の影響範囲を把握した上で変更することが大切です。
アクセス修飾子は、型の公開範囲を制御するための重要な要素であるため、一部変更するだけで他の部分にも影響が及ぶ場合があります。
コード改善の実装例と検証方法
以下のサンプルコードは、アクセス修正を行った後の実装例です。
この例は、先の誤ったコード例に対して適切なアクセス修飾子を設定し、CS0059 エラーを回避する方法を示しています。
// CS0059_Improved.cs
// 型のアクセス修飾子を public に設定して、他の public な delegate やメソッドとの整合性を確保
public class MyClass // アクセス修正済み
{
string info = "クラス情報"; // クラス内部のフィールド
}
public delegate void MyClassDelegate(MyClass instance);
public class Program
{
public static void Main()
{
// MyClass 型のインスタンス生成と delegate の呼び出しの検証
MyClass instance = new MyClass();
MyClassDelegate handler = new MyClassDelegate(DisplayInfo);
handler(instance);
}
// delegate 用のメソッド。呼び出し時に型の一致が確認できる
public static void DisplayInfo(MyClass instance)
{
System.Console.WriteLine("アクセス修正によりエラーは解消されました。");
}
}
アクセス修正によりエラーは解消されました。
まとめ
本記事では、CS0059 エラーの原因としてデリゲートのアクセスレベルとパラメーター型の不一致があることを解説しています。
型定義時にアクセス修飾子を明示的に設定する必要性や、誤ったコード例と正常な例を比較して対策を示しました。
これにより、アクセスレベルの整合性の重要性を理解できる内容となっています。