从此
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
属性之外,您无法以任何其他方式访问它.
答案很长:
快速拆卸结果.
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; }
}
}
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.MyInt
在Child
课堂上它不仅仅与实际实现相当.编译器会在预编译阶段重写自动属性.尽管字段名称将被命名为其他名称.
因此,该行为将与您手动创建属性相同.
是的隐藏字段将存在,但是它不会被分配,因为您的覆盖不会调用基本实现.
如果您将覆盖更改为
public override int MyInt
{
get { return someVar; }
set {
someVar = value;
base.MyInt = value
}
}
Run Code Online (Sandbox Code Playgroud)
然后将进行分配