CS801~2000

C#のコンパイラエラー CS1913 の原因と対策を解説

CS1913はC#のコンパイラーエラーです。

クラスのメンバーがフィールドやプロパティではない場合に、オブジェクト初期化子で初期値を設定しようとするとこのエラーが発生します。

たとえば、イベントやメソッドに初期値を割り当てるとエラーになるため、コンストラクターや他の初期化メソッドで処理を行う必要があります。

エラーの概要

このセクションでは、CS1913エラーが何であるかと、エラーの発生条件について説明します。

CS1913とは

CS1913は、C#におけるコンパイラエラーの一つで、「メンバーがフィールドでもプロパティでもないため、オブジェクト初期化子で初期化できない」という内容です。

たとえば、イベントやメソッドなど、オブジェクト初期化子では対象にならないメンバーを初期化しようとすると、このエラーが出ます。

エラー発生条件

このエラーは、以下のような条件で発生します。

  • オブジェクト初期化子を使用し、初期化対象としているメンバーがフィールドまたはプロパティでない場合
  • イベント、メソッド、またはアクセス制限のために外部から設定できないメンバーを初期化しようとした場合

オブジェクト初期化子は、読みやすさを向上させるシンタックスシュガーですが、使用できるのはアクセス可能なフィールドやプロパティに限られます。

原因の詳細解説

ここでは、エラーが発生する原因の詳細な背景について解説し、どのような制約があるのかを明らかにします。

オブジェクト初期化子の制約

オブジェクト初期化子は、オブジェクト生成時にフィールドやプロパティに対して直接値を割り当てるために用いられます。

例えば、

new Person() { Name = “太郎”, Age = 30 }

のような記述が可能です。

しかし、以下のような制約があります。

  • 初期化可能なのは、アクセス可能なフィールドやプロパティのみである
  • イベントやメソッド、あるいはprivateなメンバーに対しては使用できない

また、初期化子内で設定できるのは、メンバーに対する単純な割り当てであるため、複雑な初期化には向いていません。

初期化対象として不適切なメンバー

エラーが生じる典型的なケースは、以下のようなメンバーに対してオブジェクト初期化子を使用しようとする場合です。

  • イベント:イベントは外部から直接初期化することはできず、専用のメソッドやコンストラクターで設定する必要があります。
  • メソッド:メソッドは初期化可能なメンバーではなく、呼び出し可能な操作として実装される必要があります。
  • アクセスできないメンバー:privateなフィールドやプロパティは、オブジェクト初期化子で直接設定できません。

これらの不適切なメンバーに対して初期化を試みると、コンパイラはCS1913エラーを出力し、コードがコンパイルできなくなります。

エラー発生例の検証

このセクションでは、具体的なサンプルコードを通してエラーの原因と発生箇所について検証します。

該当コードの解説

以下のサンプルコードは、CS1913エラーが発生する典型的なケースを示しています。

コードでは、AクラスのmyEventメンバー(イベント)に対してオブジェクト初期化子で値を設定しようとしています。

コンパイラーからのエラーメッセージ解析

コンパイラーは、以下のようなエラーメッセージを出力します。

「メンバー ‘myEvent’ はフィールドでもプロパティでもないため、初期化することはできません。」

エラーメッセージは、初期化対象であるメンバーがオブジェクト初期化子に適していないことを示しています。

エラー発生箇所の説明

エラーは、オブジェクト初期化子内でmyEventに値を設定しようとした行に発生します。

メンバーの種類がイベントであるため、直接の初期化が禁止されています。

下記のサンプルコードを参照してください。

// Sample CS1913 error case
using System;
class A
{
    // イベント定義
    public delegate void DelegateMethod();
    public event DelegateMethod myEvent;
}
public class Program
{
    // Main関数
    public static void Main()
    {
        // オブジェクト初期化子でイベントに対して初期化を試みるが、これはエラーとなる
        A a = new A() { myEvent = SampleHandler };
        Console.WriteLine("この出力は到達しません");
    }
    // イベントハンドラ
    public static void SampleHandler()
    {
        // サンプル用のイベントハンドラ
        Console.WriteLine("イベントが呼び出されました");
    }
}
// コンパイルエラー CS1913 のエラーメッセージが表示される

対策方法の提案

ここでは、エラーを回避するための対策方法について解説します。

基本的な考え方は、オブジェクト初期化子で初期化できないメンバーは、コンストラクターや専用の初期化メソッドを使用して初期化することです。

コンストラクターを用いた初期化

オブジェクト初期化子で初期化できないメンバー、例えばイベントのような場合は、コンストラクター内で初期化の処理を行います。

以下は、コンストラクターを用いてイベントを初期化するサンプルコードです。

// コンストラクターでイベントを初期化する例
using System;
class A
{
    public delegate void DelegateMethod();
    public event DelegateMethod myEvent;
    // コンストラクターでイベントにハンドラを追加
    public A()
    {
        // イベントに初期ハンドラを追加する
        myEvent += SampleHandler;
    }
    // サンプルハンドラ(イベント用)
    private void SampleHandler()
    {
        Console.WriteLine("イベントがコンストラクターで初期化されました");
    }
}
public class Program
{
    public static void Main()
    {
        // コンストラクターで初期化されたインスタンスを生成
        A a = new A();
        // イベントを発火させる処理は、実際の使用ケースに応じて実装する
        Console.WriteLine("イベント初期化のサンプルプログラムです");
    }
}
// 出力結果例
イベント初期化のサンプルプログラムです

その他の初期化手法の検討

イベントや非初期化可能なメンバーに対しては、以下のような手法も考えられます。

  • 別途定義した初期化メソッドを呼び出して、メンバーの初期設定を行う
  • プロパティに変換し、setterを通して値を設定する(必要に応じたカプセル化を実現するため)

たとえば、イベントではなくプロパティとしてラップすることで初期化が可能になる場合があります。

ただし、この場合はイベントに固有の注意点があるため、意図に合った実装を検討してください。

上記の方法によって、コンパイルエラーCS1913を回避しながら正しくオブジェクトを初期化することが可能となります。

まとめ

この記事を読むと、CS1913エラーがオブジェクト初期化子でアクセスできないメンバー(イベントやメソッドなど)を初期化しようとした場合に発生することを理解できます。

また、原因の詳細な制約事項と、コンストラクターや初期化メソッドを用いた対策方法が学べ、正しい初期化手法の選択について把握できるでしょう。

関連記事

Back to top button
目次へ