CS401~800

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

CS0550は、C#においてインターフェイスに定義されていないアクセサーを派生クラスで実装した際に発生するコンパイルエラーです。

例えば、インターフェイスでgetterのみ定義されているプロパティに対して、setterを追加するとエラーが出ます。

エラーメッセージには、不要なアクセサーが含まれている旨が示されるため、仕様に沿った実装に修正する必要があります。

エラー CS0550 とは

エラー CS0550 は、インターフェイスに定義されていないアクセサー(getter や setter)が派生クラスで実装された場合に発生するコンパイルエラーです。

実装する際、インターフェイスで宣言された内容と実装が一致していないと、このエラーが出力されます。

エラーメッセージの内容

エラーメッセージには「accessor はインターフェイス メンバー property にないアクセサーを追加します」といった文言が表示されます。

このメッセージは、インターフェイスで定義されていないアクセサーが実装されていることを示しており、インターフェイスの仕様に反する実装になっているためエラーとなります。

発生する状況とケース

エラー CS0550 は、以下のような状況で発生します。

  • インターフェイスに getter だけが定義されているが、実装クラスで setter も実装している場合
  • インターフェイスに定義されないアクセサー(getter または setter)を派生クラスで誤って追加している場合

このようなケースでは、インターフェイスの契約と実装が一致しないため、コンパイラがエラーを報告します。

エラー発生の原因

エラー発生の主な原因は、インターフェイスの仕様とそれに対する実装の不整合です。

インターフェイスで定義されたプロパティが持つアクセサーと、実際にクラスで実装されるアクセサーが一致していない場合、CS0550 エラーが発生します。

インターフェイスと実装の不整合

インターフェイスで定義されるプロパティは、必要なアクセサーだけを含むため、実装クラスではその範囲内でアクセサーを実装する必要があります。

実装クラスで余分なアクセサーを追加すると、インターフェイスの仕様に反するため、コンパイラがエラーを報告します。

getter と setter の不一致

たとえば、インターフェイスで getter のみ定義されているのに対して、実装クラスで setter を実装すると、getter と setter の整合性が取れずにエラー CS0550 が発生します。

数式で示すと、もしインターフェイスのプロパティが

Property: get;

と定義されている場合、実装クラスで

Property: get;;set;

とすると不整合となります。

インターフェイスに未定義のアクセサー追加

インターフェイスが定義していないアクセサー(通常は setter か getter のどちらか)を実装クラスで追加すると、インターフェイスに存在しないアクセス機能が実装されることになり、CS0550 の原因となります。

実装する際はインターフェイスの定義に厳密に従う必要があります。

サンプルコード解析

エラーの原因をより具体的に理解するために、サンプルコードを解析します。

以下は、エラーが発生する問題のコードを示しています。

問題コードの構造

サンプルコードは、IExample インターフェイスとその実装クラス ExampleClass で構成されています。

インターフェイス IExample では、SampleProperty に getter のみが定義されていますが、実装クラス ExampleClass では、明示的なインターフェイス実装を行う際に余分な setter が追加されています。

エラー発生箇所の特定

以下のコードでは、ExampleClassIExample.SampleProperty に setter を追加している箇所がエラーの原因です。

インターフェイスには setter が存在しないため、コンパイラが CS0550 を報告します。

using System;
namespace SampleNamespace
{
    // インターフェイスに getter のみ定義
    interface IExample
    {
        int SampleProperty
        {
            get;
            // setter は定義されていない
        }
    }
    public class ExampleClass : IExample
    {
        // 明示的なインターフェイスの実装
        int IExample.SampleProperty
        {
            get
            {
                return 10; // 単純に 10 を返す
            }
            set // ここで CS0550 エラーが発生
            {
                // セット処理(本来、不要な実装)
                // 値をセットする処理を記述しようとするとエラーとなる
            }
        }
        public static void Main()
        {
            IExample example = new ExampleClass();
            Console.WriteLine(example.SampleProperty);
        }
    }
}
10

上記のコードは、実際にはエラー CS0550 によりコンパイルが通らない状態ですが、getter 部分は正常な動作が確認できるように示しています。

コンパイラ警告の解析

コンパイラは、setter の実装がインターフェイス IExample の定義に含まれていないため、CS0550 エラーを出力します。

この警告は、実装クラスにおいてインターフェイスの仕様を逸脱したアクセサーがあることを検出した場合に表示されるため、修正が必要です。

対策と修正方法

エラー CS0550 を解消するためには、インターフェイスで定義されたプロパティのアクセサーに合わせた正しい実装を行う必要があります。

具体的な対策としては、インターフェイス自体の定義を変更するか、実装クラスで不要なアクセサーを削除する方法があります。

正しいインターフェイス定義の実装

インターフェイスの定義を変更して、getter と setter の両方を必要とする場合は、以下のようにインターフェイスを修正します。

これにより、実装クラスで setter を実装してもエラーが発生しなくなります。

using System;
namespace SampleNamespace
{
    // インターフェイスに getter と setter の両方を定義
    interface IExample
    {
        int SampleProperty
        {
            get;
            set;
        }
    }
    public class ExampleClass : IExample
    {
        // 明示的なインターフェイスの実装
        int IExample.SampleProperty
        {
            get
            {
                return sampleValue;
            }
            set
            {
                sampleValue = value;
            }
        }
        private int sampleValue = 10; // 初期値の設定
        public static void Main()
        {
            IExample example = new ExampleClass();
            Console.WriteLine(example.SampleProperty); // 10 を出力
            example.SampleProperty = 20;
            Console.WriteLine(example.SampleProperty); // 20 を出力
        }
    }
}
10
20

アクセサー定義の見直し

もしプロパティが読み取り専用である場合は、実装クラス側で setter を削除することで、インターフェイスの仕様に一致させる必要があります。

この場合、インターフェイスと実装クラスでどちらも getter のみを実装する形となります。

派生クラスの正しい実装方法

インターフェイスで定義されたプロパティを正しく実装するためには、インターフェイスの仕様と一致する構造で実装を行う必要があります。

明示的なインターフェイスの実装を使用する場合でも、インターフェイスが求めるアクセサー以外の追加実装を行わないように注意してください。

修正前と修正後のコード比較

修正前のコードでは、インターフェイス IExample に getter のみ定義されているため、実装クラスで setter を追加するとエラーが発生します。

  • 修正前の実装例(エラー発生):
    • インターフェイスには getter のみ定義
    • 実装クラスで余分に setter を実装

修正後のコードでは、次のいずれかの方法でエラーを解消できます。

  1. インターフェイスに setter を追加して実装クラス側も getter/setter の両方を実装する方法
  2. 実装クラスで setter を削除し、インターフェイスの定義に合わせる方法

以下に、修正前と修正後のコード比較を示します。

  • 修正前(CS0550 エラー発生):
using System;
namespace SampleNamespace
{
    interface IExample
    {
        int SampleProperty
        {
            get;
            // setter は定義されていない
        }
    }
    public class ExampleClass : IExample
    {
        int IExample.SampleProperty
        {
            get
            {
                return 10;
            }
            set // 余分な実装によりエラー発生
            {
                // エラーとなる setter
            }
        }
        public static void Main()
        {
            IExample example = new ExampleClass();
            Console.WriteLine(example.SampleProperty);
        }
    }
}
  • 修正後(正しい実装例:実装クラス側から setter を削除):
using System;
namespace SampleNamespace
{
    interface IExample
    {
        int SampleProperty
        {
            get;
            // setter は定義しない
        }
    }
    public class ExampleClass : IExample
    {
        int IExample.SampleProperty
        {
            get
            {
                return 10;
            }
            // setter を削除してインターフェイスの定義と一致させる
        }
        public static void Main()
        {
            IExample example = new ExampleClass();
            Console.WriteLine(example.SampleProperty); // 10 を出力
        }
    }
}

このように、インターフェイスと実装クラスとのアクセサー定義を統一することで、エラー CS0550 を回避できます。

まとめ

この記事では、CS0550 エラーの原因と対策について解説しています。

インターフェイスに定義されていないアクセサーが実装クラスに追加されたことが原因でエラーが発生する点を中心に、getter と setter の不整合について説明しました。

サンプルコードを通して、エラー発生箇所の確認方法や、正しいインターフェイス定義に合わせた修正方法も紹介しています。

これにより、実装時の注意点が明確になります。

関連記事

Back to top button
目次へ