CS0~400

C# コンパイラ エラー CS0273 の原因と対策について解説

CS0273は、C#で作成したプロパティやインデクサーのアクセサーのアクセス修飾子が、対応するプロパティまたはインデクサーの修飾子より厳しくなっている場合に発生するエラーです。

たとえば、プロパティがpublicの場合に、setアクセサーをinternalに指定するとこのエラーが表示されます。

アクセス修飾子を適切に調整することで解決できます。

エラー発生条件の理解

プロパティとアクセサーの動作

C#において、プロパティはクラスや構造体内の値を取得あるいは設定するための仕組みです。

プロパティには通常、getsetのアクセサーがあり、それぞれ値の読み出しと代入を行います。

実際の動作としては、プロパティの宣言において定義されたアクセシビリティ修飾子が、getsetの処理全体に適用されます。

しかし、場合によってはgetset個別にアクセシビリティ修飾子を指定することができます。

これにより、例えば読み出しはパブリックにしつつ、書き込みをより限定的にする、といった使い方が可能です。

アクセシビリティ修飾子の制約

アクセシビリティ修飾子とは、publicinternalprotectedprivateなどのキーワードで、それぞれのメンバーへのアクセス範囲を決定します。

C#では、アクセサーに指定した修飾子は、プロパティやインデクサー自体の修飾子よりも制限が強くなる必要があります。

たとえば、プロパティがpublicとして宣言されている場合、getsetinternalprivateといったより狭いアクセス範囲の修飾子を指定することは認められています。

一方で、プロパティよりも広いアクセス範囲の修飾子を指定すると、CS0273エラーが発生します。

これは、アクセサーがプロパティの公開ポリシーを越える形でアクセス可能になることを防ぐためです。

エラーメッセージの内容

CS0273のエラー文解説

'property_accessor' アクセサーのアクセシビリティ修飾子は、プロパティまたはインデクサー 'property' よりも制限されていなければなりません

といったエラーメッセージは、プロパティやインデクサーで設定された修飾子よりも、アクセサーに設定された修飾子が緩い場合に発生します。

つまり、プロパティのアクセシビリティを例としてpublicに設定している場合に、getsetinternalなどのより広い範囲でのアクセスが許可される修飾子が設定されると、コンパイラがエラーを出力します。

このエラーは、言い換えると、アクセサーがプロパティ全体のセキュリティポリシーに反していることを示しています。

宣言された修飾子と実際の制約

プロパティ自体の修飾子が決定するアクセス範囲に合わせ、個々のアクセサーに対しても同等またはそれよりも厳しい制限を設ける必要があります。

たとえば、プロパティがpublicとして宣言されている場合、アクセサーにはprivateprotectedのような、プロパティのアクセス範囲を縮小する設定が求められます。

一方、プロパティにinternalが指定されている場合、アクセサーにpublicなどのより広いアクセス権を与えることはできません。

この制約は、クラス設計時に意図したアクセスコントロールを適切に維持するためのルールとして設けられています。

コード例を用いた解析

発生例となるコードの検証

修正前のコード例

以下のコードは、internalなプロパティに対してinternalsetを指定しているために、CS0273エラーが発生する例です。

コード内のコメントにもエラーが発生する旨を記載しています。

using System;
public class MyClass
{
    // internal なプロパティに対して、同じ internal 修飾子の set を指定しているためエラーが発生する
    internal int Property
    {
        get { return 0; }
        internal set { } // CS0273エラーが発生する行
    }
    public static void Main()
    {
        MyClass instance = new MyClass();
        Console.WriteLine(instance.Property); // プロパティの値を表示
        instance.Property = 10; // エラー発生箇所
    }
}
// コンパイル時に以下のようなエラーが発生する:
// error CS0273: 'MyClass.Property.set' アクセサーのアクセシビリティ修飾子は、プロパティまたはインデクサー 'MyClass.Property' よりも制限されていなければなりません

修正後のコード例

次に示すコードでは、setのアクセシビリティ修飾子をprivateに変更しています。

これにより、プロパティ全体の公開範囲internalを超えず、正しい設定となります。

using System;
public class MyClass
{
    // プロパティは internal として宣言し、setterは private に設定することでCS0273エラーを回避しています
    internal int Property
    {
        get { return 0; }
        private set { } // 正しいアクセシビリティ設定
    }
    public static void Main()
    {
        MyClass instance = new MyClass();
        Console.WriteLine(instance.Property); // プロパティの値を表示
        // instance.Property = 10; // 外部からはセッターにアクセスできないため変更不可
    }
}
0

エラー対策の実施方法

アクセシビリティ修飾子の適正な設定

CS0273エラーの対策として、アクセサーに指定する修飾子は常にプロパティやインデクサーの修飾子よりも制限が厳しいものである必要があります。

具体的には、プロパティがpublicである場合、アクセサーにinternalprivateを指定するのではなく、同じpublicまたはそれよりも制限の強い修飾子を使用することが求められます。

コードを書く際は、以下の点に注意してください。

  • プロパティ全体のアクセスレベルを確認する
  • 各アクセサーgetsetに指定する修飾子が、プロパティの修飾子と矛盾しないか検証する
  • 意図したアクセスコントロールが実現されるよう修飾子を選択する

コンパイルと動作確認の手順

修正後のコードは、指定されたルールに従い正しく設定されたアクセシビリティ修飾子によってコンパイルが成功するようになります。

以下の手順でコンパイルおよび動作確認を実施してください。

  • 使用している開発環境(Visual Studio、.NET CLIなど)でソースコードを保存する
  • コマンドラインまたはIDEのビルド機能を利用して、プログラムをコンパイルする

dotnet build

  • コンパイルが成功すれば、プログラムを実行して正しい出力が得られることを確認する

dotnet run

  • 実行結果が期待した出力(例:0)になっていることを確認する

以上の手順により、コードが正しく動作することを検証できるため、CS0273エラーの原因を解消した状態でプロジェクトを進行させることが可能です。

まとめ

この記事では、C#のプロパティとアクセサーの基本的な動作や、アクセシビリティ修飾子の制約について解説しています。

特に、CS0273エラーが発生する原因として、プロパティの修飾子よりも緩い設定がされている場合を説明し、具体的なコード例を用いて修正前後の違いを示しました。

また、正しいアクセス制御の設定方法と、コンパイルおよび実行手順も触れることで、エラー解消に向けた実践的方法をまとめています。

関連記事

Back to top button
目次へ