C# 3.0 自動実装プロパティがどう自動実装されるのかを調べてみた

自動実装プロパティがどう自動実装されるのか気になるので調べてみた。
なお、仕様書を読んだわけではない点に注意。

動作を調べるために使ったコンパイラ

コンパイル結果

csc にしろ gmcs にしろ、コードは以下のようになるようだ。

protected int Prop{ get; private set; }

コンパイル

[CompilerGenerated]
private int <Prop>k__BackingField;

protected int Prop{
    [CompilerGenerated]
    get{
        return this.<Prop>k__BackingField;
    }
    [CompilerGenerated]
    private set{
        this.<Prop>k__BackingField = value;
    }
}

自動実装される内容

以下のようになっているようだ。

  • private な、<プロパティ名>k__BackingField というフィールドが生成される。
  • getter / setter は、そのバッキングフィールドの値を get/set するだけ。
  • フィールド(バッキングフィールド)と getter / setter には、CompilerGeneratedAttribute が付加される。

コンパイラ実装依存&擬陽性が出うる*1ものの、上の条件を元に調べれば、リフレクションで型情報を漁る際に、自動実装されたプロパティとそれ以外を区別することもできるだろう。

実装例

Source | SVN | Assembla にあるソースコードにて、上記の内容を踏まえて、

  • 自動実装プロパティかどうかの判定
    • PropertyInfo.IsAutomacticImplimented() 拡張メソッド
  • 自動実装プロパティのバッキングフィールドの取得
    • PropertyInfo.GetBackingField() 拡張メソッド

を実装してある。
この実装例では、クラスの継承*2や override なども考慮した実装とテストを行っているので、参考までに。

*1:とはいえ、C# コンパイラが生成したのでないコードに CompileGeneratedAttribute を付けるのは自己責任だとも思う。ので、コンパイラ実装依存の方が問題だろう。

*2:private な getter, setter が見えなくなったりして厄介