48

これから

public int MyInt{ get; set;}

と同等です

private int _myInt;
public int MyInt{ get{return _myInt;} set{_myInt = value;} }

自動プロパティを仮想にするとき

public virtual int MyInt{ get; set;}

次に、子クラスでこのプロパティをオーバーライドします

public override int MyInt{ get{return someVar;} set{someVar = value;} }

この子クラスには、望ましくない非表示の _myInt 割り当てが含まれていますか?

4

4 に答える 4

55

簡単な回答:はい、ChildすべてのBaseクラス フィールドを割り当てるため、バッキング フィールドはまだ割り当てられています。Base.MyIntただし、プロパティ以外の方法でアクセスすることはできません

長い答え:

クイック分解結果。

BaseおよびChildクラスの実装:

public class Base
{
    public virtual int MyInt { get; set; }
}

public class Child : Base
{
    private int anotherInt;

    public override int MyInt
    {
        get { return anotherInt; }
        set { anotherInt = value; }
    }
}

ここに画像の説明を入力

ご覧のとおり、バッキング フィールドはBaseクラス内に存在します。Childただし、プライベートであるため、クラスからアクセスすることはできません。

.field private int32 '<MyInt>k__BackingField'

そして、あなたのChild.MyIntプロパティはそのフィールドを使用しません。プロパティ IL は次のとおりです。

.method public hidebysig specialname virtual 
    instance int32 get_MyInt () cil managed 
{
    // Method begins at RVA 0x2109
    // Code size 7 (0x7)
    .maxstack 8

    IL_0000: ldarg.0
    IL_0001: ldfld int32 ConsoleApplication2.Child::anotherInt
    IL_0006: ret
} // end of method Child::get_MyInt

.method public hidebysig specialname virtual 
    instance void set_MyInt (
        int32 'value'
    ) cil managed 
{
    // Method begins at RVA 0x2111
    // Code size 8 (0x8)
    .maxstack 8

    IL_0000: ldarg.0
    IL_0001: ldarg.1
    IL_0002: stfld int32 ConsoleApplication2.Child::anotherInt
    IL_0007: ret
} // end of method Child::set_MyInt

ご想像のとおり、 usesanotherIntフィールドです。

(プロパティ'<MyInt>k__BackingField'を介して間接的に)にアクセスする唯一の方法は次のとおりです。Base.MyInt

  • base.MyIntChildクラス内から
于 2013-08-12T08:21:02.137 に答える
2

MyInt フィールドがそこにあり、それが必要です! コンパイラは、サブクラス情報に基づく最適化を行うことができません。たとえば、パッケージ化された実行中のプログラムに派生クラスが存在しない可能性があると考えてください。

質問の一部を読み間違えたので更新しました。指摘してくれてありがとう@PVitt。

于 2013-08-12T08:27:04.247 に答える