覆盖自动属性

Tho*_*mas 47 c#

从此

public int MyInt{ get; set;}
Run Code Online (Sandbox Code Playgroud)

相当于

private int _myInt;
public int MyInt{ get{return _myInt;} set{_myInt = value;} }
Run Code Online (Sandbox Code Playgroud)

当你使自动属性虚拟

public virtual int MyInt{ get; set;}
Run Code Online (Sandbox Code Playgroud)

然后在子类中重写此属性

public override int MyInt{ get{return someVar;} set{someVar = value;} }
Run Code Online (Sandbox Code Playgroud)

这个子类现在有一个不受欢迎和隐藏的_myInt分配吗?

Mar*_*zek 54

简答:是的,Child分配所有Base类字段,因此它仍然分配了支持字段.但是,除了通过Base.MyInt属性之外,您无法以任何其他方式访问它.

答案很长:

快速拆卸结果.

BaseChild类实现:

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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

如您所见,支持字段存在于Base类中.但是,它是私有的,因此您无法从Child类中访问它:

.field private int32 '<MyInt>k__BackingField'
Run Code Online (Sandbox Code Playgroud)

而且您的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
Run Code Online (Sandbox Code Playgroud)

anotherInt正如您所料,是使用领域.

访问'<MyInt>k__BackingField'(间接,通过Base.MyInt财产)的唯一方法是:

  • base.MyIntChild课堂上

  • @SimonWhitehead您是否暗示发布模式可以优化此功能?我不会这么想,因为还有很多其他的角度,仍然需要使用支持领域. (4认同)
  • @HaseebAsif 有趣的问题。首先,我认为我不太了解这个框架:)但是更好地了解它的主要方法就是使用它,并对它感到好奇:提出问题并尝试自己回答。 (2认同)

Bob*_*ale 6

它不仅仅与实际实现相当.编译器会在预编译阶段重写自动属性.尽管字段名称将被命名为其他名称.

因此,该行为将与您手动创建属性相同.

是的隐藏字段将存在,但是它不会被分配,因为您的覆盖不会调用基本实现.

如果您将覆盖更改为

public override int MyInt
{
  get { return someVar; }
  set { 
    someVar = value;
    base.MyInt = value
  }
}
Run Code Online (Sandbox Code Playgroud)

然后将进行分配