C# コンパイラエラー CS0073 の原因と対策について解説
CS0073はC#でイベントを定義する際に、addまたはremoveアクセサーに実装ブロックを記述せずに宣言した場合に発生するコンパイラエラーです。
たとえば、addアクセサーをセミコロンだけで記述するとエラーとなるため、必ず具体的な処理内容を記述する必要があります。
エラー CS0073 の発生原因
C# のイベント定義において、アクセサーである add
や remove
に本体がない場合にエラーが発生するケースについて解説します。
ここでは、アクセサーの実装不足や実際にコードで発生するパターンを確認します。
add アクセサーの実装不足
セミコロンのみの記述による問題点
C# では、イベントアクセサーに対して単にセミコロン ;
だけを記述すると、実装が無いと判断されエラー CS0073
が発生します。
例えば、下記のサンプルコードでは add
アクセサーがセミコロンだけの記述となっており、コンパイラが実装を求めるためエラーになります。
// エラーが発生するサンプルコード
using System;
delegate void SampleDelegate(string message);
class SampleClass
{
public event SampleDelegate MyEvent
{
add; // エラー CS0073: add アクセサーには本体が必要です
remove
{
// remove アクセサーは実装されている
MyEvent -= value;
}
}
public static void Main(string[] args)
{
// Main メソッドは空でも実行可能
}
}
// コンパイル時に "CS0073" エラーが発生します
このように、add
アクセサーには具体的な処理内容を記述する必要があります。
必須の実装ブロック記述の欠落
セミコロンだけでなく、アクセサーに対して実装ブロック { ... }
が全く記述されていない場合も同様にエラーとなります。
イベントのアクセサーは明示的に本体の処理を記述しなければなりません。
実装ブロックが欠落していると、アクセサーが求める本体が存在しないためコンパイルが通りません。
remove アクセサーの実装不備
実装内容記述の不足によるエラー発生
remove
アクセサーにおいても、実装内容が記述されていなかった場合にはエラーが発生します。
例えば、remove
アクセサーをセミコロンで終了してしまうと以下のようになります。
// エラーが発生するサンプルコード
using System;
delegate void SampleDelegate(string message);
class SampleClass
{
public event SampleDelegate MyEvent
{
add
{
// 正しい実装が必要
MyEvent += value;
}
remove; // エラー CS0073: remove アクセサーには本体が必要です
}
public static void Main(string[] args)
{
}
}
// コンパイル時に "CS0073" エラーが発生します
このように、remove
アクセサーでも必ず実装ブロックが必要です。
誤った記述パターンの検証
開発環境によっては、アクセサーの記述パターンに誤りがあると、意図せずにコンパイルエラーが発生する場合があります。
正しい記述方法を再度確認することが大切です。
例えば、アクセサー内で自己参照するコードが正しいか、イベント変数へのアクセス方法が誤っていないかなど、基本パターンと比較してコードを検証することをお勧めします。
CS0073 エラーの対策方法
エラーを解消するためには、各アクセサーに実装ブロックを正しく記述することが必要です。
以下では、正しい実装方法と修正時の注意事項について解説します。
正しいアクセサー実装の手法
add アクセサーの適切な記述例
add
アクセサーには、イベントの購読処理を具体的に記述する必要があります。
下記のサンプルコードは、正しい add
アクセサーの実装例です。
using System;
delegate void SampleDelegate(string message);
class SampleClass
{
// 内部で実際にイベントを保持するための変数
private SampleDelegate sampleEvent;
public event SampleDelegate MyEvent
{
add
{
// add アクセサーでデリゲートを加算する処理を記述
sampleEvent += value;
}
remove
{
// remove アクセサーでデリゲートを減算する処理を記述
sampleEvent -= value;
}
}
public static void Main(string[] args)
{
// サンプルとしてイベントの登録・実行を行うコード
SampleClass instance = new SampleClass();
instance.MyEvent += (message) => Console.WriteLine("メッセージ: " + message);
// イベント呼び出し(内部変数経由)
instance.sampleEvent?.Invoke("こんにちは!");
}
}
メッセージ: こんにちは!
この例では、add
アクセサーに処理内容が正しく記述されているため、エラーが解消されます。
remove アクセサーの正しい記述例
remove
アクセサーも同様に、登録されたデリゲートを正しく解除する処理を記述する必要があります。
以下は、正しい remove
アクセサーの記述例です。
using System;
delegate void SampleDelegate(string message);
class SampleClass
{
private SampleDelegate sampleEvent;
public event SampleDelegate MyEvent
{
add
{
sampleEvent += value;
}
remove
{
// remove アクセサー内で、イベントからデリゲートを除去する処理を記述
sampleEvent -= value;
}
}
public static void Main(string[] args)
{
SampleClass instance = new SampleClass();
SampleDelegate handler = (msg) => Console.WriteLine("受け取った: " + msg);
instance.MyEvent += handler;
instance.MyEvent -= handler; // 正しく解除される
// イベント呼び出し(解除したため何も出力されません)
instance.sampleEvent?.Invoke("テストメッセージ");
}
}
// 出力はありません(イベントハンドラが解除されているため)
修正時の留意点
コード修正時の注意事項
アクセサーの修正を行う際は、イベントの内部管理方法を検討することが必要です。
特に以下の点に注意してください。
- 内部変数に対して加算・減算の処理が正しく行われるか確認する
- 複数スレッド環境での同時アクセスに備える場合は、適切な同期処理を検討する
- ユーザーがイベントに正しくアクセスできるよう、アクセサーの記述ミスがないかコードレビューを実施する
これらの対策により、アクセサーに関わるエラーを防止し、コードが意図した通りに動作します。
エラー回避のための実装ポイント
アクセサーのエラー回避には、以下のポイントが役に立ちます。
- 正確な実装ブロック
{ ... }
を記述する - 単純なセミコロンでの記述は避ける
- Visual Studio などのコンパイルエラー表示を活用し、エラーメッセージにしたがって修正内容を反映する
- イベントに付随するアクセサーの処理が正しく実装されているか、テストコードで確認する
これにより、コンパイルエラー CS0073 を回避することができます。
まとめ
本記事では、C# のイベント定義における CS0073 エラーの原因とその対策方法について解説しました。
特に、add
および remove
アクセサーが実装不足の場合にエラーが発生する点を具体例とともに説明し、正しい実装例や修正時の注意事項を示しました。
これにより、イベントハンドラの登録・解除が正しく行われるコードの記述方法が理解できます。