C# コンパイラ エラー CS0277 の原因と解決方法を解説
CS0277は、C#でインターフェイスのメンバーを実装する際に、プロパティのアクセッサがpublicになっていない場合に発生するコンパイルエラーです。
たとえば、インターフェイスで定義されたプロパティを実装する際に、setterがprotectedなどになっているとこのエラーが出ます。
エラーを解消するには、アクセッサをpublicに変更するか、アクセス修飾子を削除してインターフェイスの仕様に従った実装に修正します。
CS0277エラーの概要
CS0277エラーは、インターフェイスのプロパティ実装において、クラス側で実装するアクセサがインターフェイスで要求されるpublicなアクセス修飾子と一致しない場合に発生するエラーです。
エラーメッセージは「‘class’ はインターフェイス メンバー ‘accessor’ を実装しません。
‘class accessor’ は public ではありません」と表示され、実装不足を示唆しています。
エラーの定義
このエラーは、インターフェイスに定義された全てのメンバー(特にプロパティ)の実装がpublicでなければならないという規則に基づいています。
例えば、インターフェイスでget
とset
が定義されているプロパティは、クラス側で実装する際に、どちらのアクセサもpublicである必要があります。
アクセス修飾子の不一致がある場合、コンパイラーはCS0277エラーを出力します。
発生条件
エラーは、以下の場合に発生します。
- インターフェイスで定義されたプロパティの
set
またはget
アクセサが、クラス側でpublic以外のアクセス修飾子(たとえばprotected
やprivate
)で実装されている場合 - 実装時にアクセス修飾子を明示しなかった場合(この場合、暗黙的にpublicと認識されますが、状況により誤解が生じる可能性があります)
エラー発生の原因
CS0277エラーの主な原因は、インターフェイスの実装規則に沿っていないことです。
具体的な原因は以下の通りです。
インターフェイス実装の規則
インターフェイス内の全てのメンバーは、クラスで実装される際にpublicである必要があります。
インターフェイス自体がメンバーに対してアクセス修飾子を指定できないため、クラス側で明示的にpublicにする必要があります。
プロパティアクセサのpublic要件
インターフェイスに定義されたプロパティは、get
とset
が暗黙的にpublicな契約を定義しています。
そのため、クラスで実装する際も両アクセサともpublicでなければなりません。
もし、たとえばprotected set
として実装すると、インターフェイスの契約と矛盾し、CS0277エラーが発生します。
クラス側実装でのアクセス修飾子の不整合
クラス側でプロパティの実装を行う時に、アクセス修飾子を間違って指定するとエラーが生じます。
特に、getterはpublicであるにもかかわらず、setterがprotectedやprivateになっている場合、インターフェイスの要求であるpublicなsetterと不整合があり、エラー対象となります。
エラー解決の方法
CS0277エラーを解消するためには、プロパティアクセサーのアクセス修飾子をインターフェイスの要求通りに、すなわちpublicに変更する必要があります。
以下で、具体的な対策方法について説明します。
アクセス修飾子の調整方法
実装を見直し、インターフェイスの契約に沿ってアクセス修飾子を正しく指定する方法が有効です。
具体的な手法としては以下の通りです。
publicへの変更
プロパティのgetterおよびsetterの両方をpublicに変更します。
これにより、インターフェイスの公开な契約と合致させることができます。
下記の例では、setterがprotectedとなっていたためエラーが生じた状態です。
正しくは、双方ともpublicにする必要があります。
アクセサ修飾子の省略による実装例
C#では、プロパティ実装時にアクセス修飾子を省略すると、クラスのメンバーはデフォルトでpublicにならない場合があります。
しかし、インターフェイス実装の場合は、明示的にpublicと記述するか、正しく初期化された自動実装プロパティを使うと、適切なアクセスレベルが適用されるため、エラーを防ぐことができます。
コード例による検証
以下に、エラーが発生するコード例と、その修正例を示します。
両方の例にはMain
関数を含め、実行可能な形で記述しています。
発生例のコード分析
次のサンプルコードは、CS0277エラーが発生するケースを示しています。
エラーは、インターフェイスで定義されたプロパティのset
アクセサが、実装クラスでprotected
として定義されている箇所で発生します。
エラー箇所の特定
下記のコードでは、MyInterface
のプロパティProperty
のset
が、MyClass
においてprotected
になっているため、インターフェイスの契約と不整合となり、CS0277エラーが発生します。
using System;
public interface MyInterface
{
int Property { get; set; } // インターフェイスでは暗黙的にpublic
}
public class MyClass : MyInterface
{
public int Property
{
get { return 42; } // publicなgetter
protected set { } // ここがエラーの原因です
}
}
public class Program
{
public static void Main()
{
// インターフェイス経由でクラスのプロパティにアクセスします
MyInterface obj = new MyClass();
Console.WriteLine(obj.Property);
}
}
// コンパイル時にエラー: 'MyClass.Property.set' はインターフェイス 'MyInterface.Property' を実装していません。
修正例のコード検証
正しい実装例の詳細解説
以下のコードは、プロパティのgetterとsetterの両方をpublicにすることで、CS0277エラーを解消した例です。
プロパティ実装がインターフェイスの要求通りになっているため、正常にコンパイルおよび実行できます。
using System;
public interface MyInterface
{
int Property { get; set; } // インターフェイスでは暗黙的にpublic
}
public class MyClass : MyInterface
{
// 自動実装プロパティを使用して、getterとsetterが共にpublicとなっています
public int Property { get; set; }
}
public class Program
{
public static void Main()
{
// インターフェイス経由でプロパティにアクセスし、値を設定および出力します
MyInterface obj = new MyClass { Property = 100 };
Console.WriteLine(obj.Property);
}
}
100
まとめ
この記事では、C#におけるCS0277エラーの発生原因とその解決策について解説しています。
インターフェイスで定義されたプロパティは、クラス側で実装する際に必ずpublicなアクセサにする必要があること、またクラス実装でのアクセス修飾子の不整合がエラーを引き起こす点を確認できます。
さらに、実際のサンプルコードを通して、エラー箇所の特定方法と正しい実装例をわかりやすく解説しているため、コード実装時のトラブルシューティングに役立ちます。