式形式のメンバーとか式本体の定義とか

《 初回公開:2020/07/12 , 最終更新:未 》

visual studio2019 C#8.0で動作確認。

c# expression-bodied

英語ではExpression-bodied members
日本語では式が本体となるとか式形式のメンバーと訳されるかかな。

そして、「An expression body definition(式本体の定義)」とも言われるみたいで
式形式のメンバーはラムダ式と同様、=> トークンを使って表現される。

member => expression;

memberには次のものが許される。

  • メソッド
  • プロパティ
  • コンストラクター
  • ファイナライザー
  • インデクサ

expressionには "ステートメント式" である必要がある。

ステートメント式といのはどういう式を意味するのかよくわからないが多分、1つの式だけからなるものを言うらしい。

式形式のメンバーを持つクラスの例を以下に示す。

class MyClass
{
    // 式形式の読み取り専用のプロパティ
    public string ReadOnlyName => "xxx";
    // 式形式の読み書きができる一般的なプロパティ
    private string _name;
    public string Name
    {
        get => _name;
        set => _name = value;
    }
    // 式形式のコンストラクタ
    public MyClass(string name) => Name = name;
    // 式形式のメソッド
    public override string ToString() => $"{GetType().Name}: Name = {Name} , ReadOnlyName = {ReadOnlyName}";
    // 式形式のファイナライザ
    ~MyClass() => Console.WriteLine($"The {ToString()} destructor is executing.");

    private string[] types = { "Baseball", "Basketball", "Football",
                      "Hockey", "Soccer", "Tennis",
                      "Volleyball" };
    // 式形式のインデクサ
    public string this[int i]
    {
        get => types[i];
        set => types[i] = value;
    }
}

上記のコードは以下のコードと等価。

式形式を使わないと

class MyClass
{
    // 読み取り専用のプロパティ
    public string ReadOnlyName { get; } = "xxx";
    // 読み書きができる一般的なプロパティ
    private string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
    // コンストラクタ
    public MyClass(string name) { Name = name; }
    // メソッド
    public override string ToString() { return $"{GetType().Name}: Name = {Name} , ReadOnlyName = {ReadOnlyName}"; }
    // ファイナライザ
    ~MyClass() { Console.WriteLine($"The {ToString()} destructor is executing."); }

    private string[] types = { "Baseball", "Basketball", "Football",
                  "Hockey", "Soccer", "Tennis",
                  "Volleyball" };
    // インデクサ
    public string this[int i]
    {
        get { return types[i]; }
        set { types[i] = value; }
    }
}

クラスのstaticメンバーに対しても式形式で記述する事が出来て
上記の式形式のメンバーをstaticに変更してみると

class MyClass
{
    static public string ReadOnlyName => "xxx";
    static private string _name;
    static public string Name
    {
        get => _name;
        set => _name = value;
    }
    // staticなコンストラクタは引数を持てない。
    static MyClass() => Console.WriteLine();

    public override string ToString() => $"{GetType().Name}: Name = {Name} , ReadOnlyName = {ReadOnlyName}";
    // ファイナライザはstaticにできない
    // static ~MyClass2() => Console.WriteLine($"The {ToString()} destructor is executing.");

    static private string[] types = { "Baseball", "Basketball", "Football",
                  "Hockey", "Soccer", "Tennis",
                  "Volleyball" };
    // インデクサはstaticにできない
    /* static public string this[int i]
    {
        get => types[i];
        set => types[i] = value;
    }*/
}

但し、もともとインデクサやファイナライザはstaticには指定できない。

staticなコンストラクタは引数を持てないのでコードの修正が必要。


参考記事

試してはいないがイベントでも使えるみたい。

ページのトップへ戻る