6

プロパティステートメント自体がプロパティであるかどうかを記述する必要があるため、これはプロパティを使用する VB.NET では可能ではないようですReadOnly

ReadWriteChild以下の例では、コンパイルできません。親を読み取り/書き込み可能にしてから、ReadOnlyChild のセッターに何もさせないようにすることもできると思いますが、それは一種のハッキーに思えます。この場合の最良の代替手段は、getter/setter メソッドを優先してプロパティを放棄することです。

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
4

7 に答える 7

6

あなたが達成しようとしていることと、投稿したサンプル コードを考えると、VB.NET ではこれを実行できません。

通常、次のように VB.NET でプロパティを宣言できます。

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

基本的にプロパティ全体を public としてマークしますが、setter (または getter) により限定的なスコープを与えます。

あなたの場合の主な問題は、MustInherit (つまり、抽象) 基本クラスです。そこで定義しているプロパティは MustOverride としてマークされているため、デフォルトの実装を提供することはできません (つまり、それも抽象的です)。これには、"Get" および "Set" アウトラインが含まれます。この抽象プロパティ宣言に " スコープを指定すると、VB.NET は、派生クラス内のゲッターとセッターの両方にこのスコープを使用することを強制します。

基本クラスのプロパティに ReadOnly 修飾子を指定すると、すべての派生クラスとこのプロパティの実装も強制的に ReadOnly になります。抽象プロパティに与えるスコープは、派生実装内のセッターとゲッターの両方に適用する必要があるスコープになるため、ReadOnly 修飾子を除外しても機能しません。

例えば:

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

(setter のプライベート スコープに注意してください)。VB.NET は、基本クラスのプロパティをオーバーライドしているため、プロパティ全体がオーバーライドしているプロパティ (この場合はパブリック) と同じスコープを持つ必要があると主張しているため、これは機能しません。

基本クラスの抽象プロパティを保護しようとしても機能しません。基本クラスで宣言されているのと同じレベルのスコープでプロパティを実装する必要があるためです (つまり、保護されています)。通常、基本クラスの抽象定義を特定のスコープ レベルでオーバーライドしない場合、getter または setterにより制限的なスコープ レベルを与えることはできますが、より制限の少ないスコープ レベルを与えることはできません。

したがって:

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

(getter のパブリック スコープに注意してください)。public スコープが protected の全体的なプロパティ スコープよりも制限が少なく、さらに、基本クラスの抽象プロパティ宣言で定義されているスコープ レベルと同じでないため、機能しません。

あなたのクラスの設計があなたの質問で述べたとおりであれば、私は個人的に、「Java スタイル」のゲッター メソッドとセッターメソッドを使用します。これらのメソッドは、独自のスコープ レベルで個別に宣言できるからです。

于 2009-02-16T21:09:32.377 に答える
3

大当たりかもしれません...VB.NETに関する私の知識が最小限であることを考えると...

C# では、プロパティとは別に、プロパティ アクセサーの可視性を指定できます。

public virtual string Name
{
    get { ... }
    protected set { ... }
}

この例では、子クラスは settor にアクセスできますが、他のクラスはアクセスできません。

また、オーバーライドは、オーバーライドするものよりも可視性が高くなる可能性があることに注意してください。そのため、次のようにすることができます。

public overide string Name
{
    get { ... }
    public set { ... }
}

VB.NET でこのようなことができますか?

于 2009-02-16T20:06:36.803 に答える
2

Shadow が使えるという点で MrEdmuno が正しいことを確認します。ただし、MustInherit とマークされているものを直接シャドーできないように見えるため、クラス (親 2) に継承する必要があります。次に、読み取り専用に継承します (実際に考えてみると、クラスに継承します)

私のコメントの質問はまだ残っていると思いますが、なぜこれを行う必要があるのですか? それらが独自のクラスである場合、それらを変更するか、インターフェイスとして実装する方がよいでしょうか?

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
            Return "Return"
        End Get
    End Property

End Class

Public Class Parent2
    Inherits Parent

    Public Overrides ReadOnly Property Foo() As String
        Get
            Return "Return 2"
        End Get
    End Property
End Class

Public Class ReadWriteChild
    Inherits Parent2

    Public Shadows Property Foo() As String
        Get
            '// Get the property.
            Return "2"
        End Get
        Set(ByVal value As String)
            '** Set something
        End Set
    End Property
于 2009-02-16T21:25:52.323 に答える
0

仮想ではないため、プロパティをオーバーライドしようとしないでください。OnReadOnlyChanged メソッドをオーバーライドして、そこでビジネスを処理します。幸運を

于 2010-06-21T18:30:28.397 に答える
0

別のレベルの階層を追加する必要があります。残念ながら、実際に適切にスコープを設定する唯一の方法は、ネストされたクラスを使用することです。

Public Class IntermediateClassForPrivateInheritanceOnly
  Inherits Parent
  Public Overrides ReadOnly Property Foo() As String
  ' etc.
  Private Sub New(whatever)
    MyBase.New(whatever)
  End Sub

  ' Most other stuff for the class goes here.

  Public Class ReadWriteChild
    Inherits IntermediateClassForPrivateInheritanceOnly
    Shadows Property Foo()
    ' etc.
    Public Sub New(whatever)
      MyBase.New(whatever)
    End Sub
  End Class
End Class

Public Class ReadWriteChild  ' Would use an alias, if such things existed
  Inherits IntermediateClassForPrivateInheritanceOnly
  Public Sub New(whatever)
    MyBase.New(whatever)
  End Sub
End Class
于 2010-12-20T19:47:55.707 に答える
0

Bevan が提案したことに対処するために、VB.NET では、次のように、パブリック ゲッターと保護されたセッターを持つプロパティを宣言できます。

Private _ExpectedTotalRoyalties As Decimal

Public Property ExpectedTotalRoyalties() As Decimal
    Get
        Return _ExpectedTotalRoyalties
    End Get
    Protected Set(ByVal value As Decimal)
        If Not _ExpectedTotalRoyalties.Equals(value) Then
            _ExpectedTotalRoyalties = value
            SendPropertyChanged("ExpectedTotalRoyalties")
        End If
    End Set
End Property
于 2009-05-03T10:24:17.723 に答える
0

残念ながら、私はここにビジュアルスタジオを持っていないので、確認できません.

Shadows の使用を見たことがありますか。これは、C# のプロパティ宣言で "new" と言うのと事実上同じです。

于 2009-02-16T21:08:54.330 に答える