在子类中重写只读属性,使其读/写(VB.NET或C#) [英] Overriding ReadOnly Property in a subclass to make it Read/Write (VB.NET or C#)

查看:1259
本文介绍了在子类中重写只读属性,使其读/写(VB.NET或C#)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这似乎并不可能在VB.NET与性能,因为物业语句本身必须描述它是否是只读或没有。



在我下面的例子中,它不会让我的 ReadWriteChild 编译。我想我可以使父读/写,然后有ReadOnlyChild的setter没有做任何事情,但这似乎排序哈克。最好的选择似乎是放弃赞成在这种情况下,getter / setter方法的属性。



<预类=朗动prettyprint-覆盖> 公众为MustInherit类父

公共MustOverride ReadOnly属性美孚()作为字符串

端类

公共类ReadOnlyChild
继承父

公共覆盖只读属性美孚()作为字符串
得到
'获得属性
端获取
高端物业

端类

类公共ReadWriteChild
继承父

公共属性覆盖美孚()作为字符串
得到
'取得属性。
端获取
组(BYVAL值作为字符串)
设置属性。
端设置
高端物业

端类


解决方案

由于你想要什么来完成,并与您发布的示例代码,VB.NET不会让你这样做。



通常情况下,你可以在VB.NET声明一个属性,像这样:



<预类=朗动prettyprint-覆盖> 公共类qwqwqw
公共财产的xyz()作为字符串
得到
返回,
端获取
私人设置(BYVAL值作为字符串)
'
端设置
高端物业
端类

基本上标志着整个财产大众,而是给人一种更严格的范围setter方法(或getter)。



在你的情况,主要问题是为MustInherit(即抽象)基类。既然你在那里定义属性标记为MustOverride,你不能提供一个默认的实现(即它,太,是抽象的),这包括获取和设置轮廓,因此,取其的总体你给这个抽象的财产申报范围,VB.NET将迫使你用这个余地的两个的派生类中的getter和setter方法。



有基类的属性将强制所有派生类与这个属性的实现也成为只读的只读预选赛。离开关只读预选赛仍然无法工作,因为你给抽象属性的任何范围将是你必须派生出来的系统内,向getter和setter方法既范围。



例如:



<预类=朗动prettyprint-覆盖> 公开为MustInherit类父
公共MustOverride属性美孚()作为字符串
端类

公共类ReadOnlyChild
继承父

公共覆盖物业美孚()作为字符串
得到
'
端获取
私人设置(BYVAL值作为字符串)
'
端设置
高端物业
端类

(注意在二传手的私有作用域)。这将无法正常工作,VB.NET坚持要因为你重写基类物业,整个物业必须具有相同的范围,因为你重写属性(在这种情况下,公共)。



试图使基类的抽象属性的保护将不能工作,因为你会再被要求在范围界定的相同水平,因为它在你的基类的政府在宣布实行的财产(即保护) 。通常情况下,当不重写基类的抽象定义与特定的作用域级别,你可以给一个getter或setter一个的更多的限制作用域的水平,但你不能给它的

<预类=朗动prettyprint-覆盖> <$:EM>限制的作用域级别



C $ C>公开为MustInherit类父
受保护的MustOverride属性美孚()作为字符串
端类

公共类ReadOnlyChild
继承父

保护的覆盖物业美孚()作为字符串
公共得到
'
端获取
组(BYVAL值作为字符串)
'
端套装
高端物业
端类

(注意吸气剂公众作用域)。无法正常工作或因公范围比受保护的整体物业范围限制较少,而且,没有对基类的抽象属性声明定义相同的作用域级别。



如果你的类的设计,你在你的问题提了,我个人而言,会去与一个Java风格getter和setter的方法的,因为它们可以被分别与申报他们自己的范围级别。


This doesn't seem possible in VB.NET with properties since the property statement itself must describe whether it is ReadOnly or not.

In my example below, it doesn't let me make the ReadWriteChild compile. I guess I could make the parent Read/Write, and then have the ReadOnlyChild's setter not do anything, but that seems sort of hacky. The best alternative seems to be abandoning properties in favor of getter/setter methods in this case.

Public MustInherit Class Parent

    Public MustOverride ReadOnly Property Foo() As String

End Class

Public Class ReadOnlyChild
    Inherits Parent

    Public Overrides ReadOnly Property Foo() As String
        Get
            ' Get the Property
        End Get
    End Property

End Class

Public Class ReadWriteChild
    Inherits Parent

    Public Overrides Property Foo() As String
        Get
            ' Get the property.
        End Get
        Set(ByVal value As String)
           ' Set the property.
        End Set
    End Property

End Class

解决方案

Given what you're trying to accomplish, and with the sample code you posted, VB.NET will not let you do this.

Ordinarily, you can declare a property in VB.NET like so:

Public Class qwqwqw
  Public Property xyz() As String
      Get
          Return ""
      End Get
      Private Set(ByVal value As String)
          '
      End Set
  End Property
End Class

Basically marking the overall property as public, but giving a more restrictive scope to the setter (or getter).

The main problem in your case is the MustInherit (i.e. abstract) base class. Since the property you're defining in there is marked as MustOverride, you can't provide a default implementation (i.e. it, too, is abstract), and this includes the "Get" and "Set" outlines, therefore, whichever "overall" scope you give to this abstract property declaration, VB.NET will force you to use this scope for both the getters and setters within derived classes.

Having the ReadOnly qualifier on the base class's property will force all derived classes and the implementations of this property to also be ReadOnly. Leaving off the ReadOnly qualifier still will not work, since whatever scope you give to the abstract property will be the scope you must apply to both the setters and getters within derived implementations.

For example:

Public MustInherit Class Parent
  Public MustOverride Property Foo() As String
End Class

Public Class ReadOnlyChild
  Inherits Parent

  Public Overrides Property Foo() As String
    Get
        '
    End Get
    Private Set(ByVal value As String)
        '
    End Set
  End Property
End Class

(Note the Private scoping on the setter). This will not work as VB.NET is insisting that since you're overriding the base classes property, your entire property must have the same scope as the property you're overriding (in this case, public).

Attempting to make the base class's abstract property protected will not work either, since you would then be required to implement the property at the same level of scoping as it's declared in your base class (i.e. protected). Ordinarily, when not overriding a base class's abstract definition with a specific scoping level, you can give a getter or setter a more restrictive scoping level, but you can't give it a less restrictive scoping level.

Therefore:

Public MustInherit Class Parent
  Protected MustOverride Property Foo() As String       
End Class

Public Class ReadOnlyChild
  Inherits Parent

  Protected Overrides Property Foo() As String
      Public Get
          '
      End Get
      Set(ByVal value As String)
          '
      End Set
  End Property
End Class

(Note the public scoping on the getter). Doesn't work either due to the public scope being less restrictive than the overall property scope of protected, and moreover, not of the same scoping level as defined on the base class's abstract property declaration.

If the design of your classes is as you mention in your question, I personally, would go with a "java-style" getter and setter methods as they can then be declared separately with their own scoping levels.

这篇关于在子类中重写只读属性,使其读/写(VB.NET或C#)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆