加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

为什么C#中的完整属性只能被一个getter覆盖,但它仍然可以被设置

发布时间:2020-12-15 04:34:47 所属栏目:百科 来源:网络整理
导读:我遇到了令我惊讶的行为.给出以下两个类: class Parent{ public virtual bool Property { get; set; }}class Child : Parent{ public override bool Property { get = base.Property; }} 我可以写这样的代码: Child child = new Child();child.Property =
我遇到了令我惊讶的行为.给出以下两个类:
class Parent
{
    public virtual bool Property { get; set; }
}

class Child : Parent
{
    public override bool Property { get => base.Property; }
}

我可以写这样的代码:

Child child = new Child();
child.Property = true; // this is allowed

IDE也让它变得混乱,因为虽然它允许赋值,但它也表明被覆盖的属性是只读的:

此外,只有在我使用基类’getter时才允许此覆盖:

这里发生了什么?

解决方法

我会对此嗤之以鼻.

看起来这可能只是Intellisense的一个错误,它无法找到自动属性的基本实现.代码是有效的,也是有道理的 – 这是表达你的例子的另一种方式.

Child child = new Child();
child.SetProperty(true);

class Parent
{
    private bool _property;

    public virtual bool GetProperty() => _property;
    public virtual void SetProperty(bool value) => _property = value;
}

class Child : Parent
{
    public override bool GetProperty() => base.GetProperty();
}

有了这种表示,现在很明显为什么重写GetProperty很好.这是您的代码的相关IL:

Main:
IL_0000:  newobj      Child..ctor
IL_0005:  ldc.i4.1
IL_0006:  callvirt    Parent.set_Property
IL_000B:  ret

Parent.get_Property:
IL_0000:  ldarg.0
IL_0001:  ldfld       Parent.<Property>k__BackingField
IL_0006:  ret

Parent.set_Property:
IL_0000:  ldarg.0
IL_0001:  ldarg.1
IL_0002:  stfld       Parent.<Property>k__BackingField
IL_0007:  ret

Parent..ctor:
IL_0000:  ldarg.0
IL_0001:  call        System.Object..ctor
IL_0006:  ret

Child.get_Property:
IL_0000:  ldarg.0
IL_0001:  call        Parent.get_Property
IL_0006:  ret

Child..ctor:
IL_0000:  ldarg.0
IL_0001:  call        Parent..ctor
IL_0006:  ret

这是我的版本:

Main:
IL_0000:  newobj      Child..ctor
IL_0005:  ldc.i4.1
IL_0006:  callvirt    Parent.SetProperty
IL_000B:  ret

Parent.GetProperty:
IL_0000:  ldarg.0
IL_0001:  ldfld       Parent._property
IL_0006:  ret

Parent.SetProperty:
IL_0000:  ldarg.0
IL_0001:  ldarg.1
IL_0002:  stfld       Parent._property
IL_0007:  ret

Parent..ctor:
IL_0000:  ldarg.0
IL_0001:  call        System.Object..ctor
IL_0006:  ret

Child.GetProperty:
IL_0000:  ldarg.0
IL_0001:  call        Parent.GetProperty
IL_0006:  ret

Child..ctor:
IL_0000:  ldarg.0
IL_0001:  call        Parent..ctor
IL_0006:  ret

请注意,这与公共覆盖bool Property {get; },是指示编译器为同名的后备属性生成单个getter覆盖的简写,没有提到预先存在的setter.然而,有实际规格经验的人肯定能够提供更多相关信息.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读