G-W*_*Wiz 7 .net c# compiler-construction c#-3.0
病态的好奇心.说我有这种层次结构:
class Base {
public virtual int Field { get; set; }
}
class Derived : Base {
int _field;
public override int Field { get { return _field; } set { _field = value; } }
}
Run Code Online (Sandbox Code Playgroud)
如果我实例化Base,编译器将神奇地为Field属性创建一个支持字段.
因此,Derived如果没有引用基本实现,那么在Derived实例化时是否会创建支持字段?这是在C#规范中指定的,还是留给编译器实现?
更新
事实证明,规范确实特别声明自动实现的属性是使用"隐藏的支持字段"实现的.(第10.7.3节)我的具体问题没有任何说法.假设"隐藏"一词指的是new关键字提供的相同成员隐藏功能,我必须得出结论,无论使用什么,始终都会创建支持字段.
我想一个相关的问题可能是"是否为永远不会访问的自动实现的属性创建了支持字段?" 相同的基本论点,相同的结论.
此示例程序演示了支持字段的创建。调用返回以下示例中的GetFields支持字段。Int32 <Field>k__BackingField您可以通过反射设置和获取该字段的值,但不能通过实例derived。Derived您还可以看到,当您通过反射更新字段时,不会调用在类上声明的 setter 。
void Main()
{
var derived = new Derived();
derived.Field = 10;
var fieldInfo = typeof(Base).GetFields(
BindingFlags.NonPublic | BindingFlags.Instance)[0];
fieldInfo.SetValue(derived, 20);
Console.WriteLine(derived.Field);
Console.WriteLine(fieldInfo.GetValue(derived));
}
public class Base {
public virtual int Field { get; set; }
}
public class Derived : Base {
int _field;
public override int Field
{
get { return _field; }
set { Console.WriteLine("Setter called."); _field = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
该程序的输出是:
Setter called.
10
20
Run Code Online (Sandbox Code Playgroud)
FieldInfo与调用返回的实例一起写出的 20 值GetFields表明已创建支持字段。