泥庭

2015年7月22日

【C#6.0】プロパティー新機能

Filed under: .NET, C# — タグ: , — yone64 @ 12:03 AM
Visual Studio 2015が、無事(?)リリースされました。というわけで、C#6.0絡みの新機能を試してみた記録を残しておきます。
とりあえず、プロパティー周りから。
# C#6.0の新機能とか、あちこちで以前から書かれているので、特に新しい情報はないと思われ。

新しく読取専用の自動実装プロパティーがふえました。
// 以前からの自動実装プロパティー
public int MyProperty1 { get; set; }
public int MyProperty2 { get; private set; } // getとsetに別々のアクセッサを適用できる

// 新しく、getのみのものが追加された。
public int MyProperty3 { get; }

//// こんな感じに展開される
//private readonly int <MyProperty3>k__BackingField;
//public int MyProperty3
//{
//    get { return <MyProperty3>k__BackingField; }
//}
readonly fieldとほぼ同じふるまいをし、宣言時orコンストラクタ内でのみ初期化可能です。
public class Hoge
{
    // 宣言時に初期化
    public int MyProperty { get; } = 1;

    public Hoge()
    {
        // コンストラクタ内で初期化
        this.MyProperty = 2;
    }

    public void Fuga()
    {
        // コンパイルエラー(通常のメソッドでは代入できない)
        //this.MyProperty = 3;
    }
}
自動実装プロパティーの宣言時に初期化できるようになりました。
# 上記の読取専用のところで先にちょっと出てますね。(^^
基本的にはコンストラクタで初期値を設定するのと同じような振る舞いなのですが、コンストラクタを利用した初期値設定はPropertyのsetを通して初期値設定されるのに対し、宣言時の初期値設定はbacking fieldへ直接値が代入されています。
なお、読取専用自動実装プロパティーはそもそもgetterしかないため、コンストラクタ内で初期化してもbacking fieldへ直接値が代入されます。
初期化時に他のインスタンスメンバを参照できなかったりするのは、fieldの初期化と同じですね。
public class Hoge
{
    // 宣言時の初期化はすべて、backing fieldへ直接代入される。
    public int MyProperty { get; set; } = 1;
    public int MyProperty2 { get; private set; } = 2;
    public int MyProperty3 { get; } = 3;


    public Hoge()
    {
        // property の set を通して設定される
        this.MyProperty = 11;
        this.MyProperty2 = 12;

        // backing fieldへ直接代入される
        this.MyProperty3 = 13;
    }
}
そのため普通はかかないと思いますが、下記コードみたいなのを実行すると結果が異なってきます。
(かなり悪意を持ったコードw
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(new Sub().MyProperty);  // 2 が表示される
        Console.WriteLine(new Sub().MyProperty2); // 1 が表示される
    }
}

public class Super
{
    public virtual int MyProperty { get; set; }
    public virtual int MyProperty2 { get; set; } = 1;
    public Super()
    {
        this.MyProperty = 1;
    }
}

public class Sub : Super
{
    public override int MyProperty
    {
        get
        {
            return base.MyProperty;
        }

        set
        {
            base.MyProperty = value + 1;
        }
    }

    public override int MyProperty2
    {
        get
        {
            return base.MyProperty2;
        }

        set
        {
            base.MyProperty2 = value + 1;
        }
    }
}
get-only なプロパティーの本体をラムダ形式で書けるようになりました。
メソッドボディーがラムダ形式で書けるようになったのと絡むので、たぶん次回以降(あるのか?)再登場すると思います。
class Hoge
{
    public int X { get; set; }
    public int Y { get; set; }

    // こんな書き方ができるようになりました。
    public int Sum => X + Y;

    // ↓と同義です。
    public int Sum1
    {
        get
        {
            return X + Y;
        }
    }

    // こう書くとメソッドなので、少し紛らわしい。
    public int Sum2() => X + Y;

    // > が抜けると、フィールドになっちゃうし、要注意?
    // この場合は、他のインスタンスメンバを参照してるので、コンパイルエラーだが
    public int Sum3 = X + Y;
}
という感じで、さらっと終了です。
# ところで、get-onlyな自動実装プロパティーにコードスニペットないのでしょうか?
# propgで、private set版ではなく、こっちが出てほしい感あるよね。
広告

コメントする »

まだコメントはありません。

RSS feed for comments on this post. TrackBack URI

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

WordPress.com Blog.

%d人のブロガーが「いいね」をつけました。