3

クラスからクイック リストを生成できるようにするためのシンプルなインターフェイスを開発しようとしています。基本的に、インターフェイスは ID と名前を返す必要があります。ただし、読み取り専用の計算された名前プロパティを持つクラスもあれば、読み取り/書き込み可能な名前プロパティのみを使用するクラスもあります。基本的に、プロパティにセッターがあるかどうかは関係ありません。このインターフェイスを記述して、コンパイル エラーをスローするか、スローせずに処理するにはどうすればよいですか?

私はこの質問を読みましたが、実際には従いませんでした。多分私はただ密集しています。もしそうなら、私のやり方の誤りを教えてください:)

4

1 に答える 1

5

他の質問からの答えがうまくいくように見えます:ここにサンプルがあります:

Public Interface IReadOnly
    ReadOnly Property Name() As String
End Interface

Public Interface IReadWrite
    Inherits IReadOnly

    Overloads Property Name() As String

End Interface

Public Class ReadOnlyClass
    Implements IReadOnly

    Private _Name
    Public ReadOnly Property Name() As String Implements IReadOnly.Name
        Get
            Return _Name
        End Get
    End Property
End Class

Public Class ReadWriteClass
    Implements IReadWrite

    Private ReadOnly Property ReadOnly_Name() As String Implements IReadOnly.Name
        Get
            Return Name
        End Get
    End Property

    Private _Name As String
    Public Overloads Property Name() As String Implements IReadWrite.Name
        Get
            Return _Name
        End Get
        Set(ByVal value As String)
            _Name = value
        End Set
    End Property
End Class

上記のアプローチでは、実際には IReadWrite を実装するクラスも IReadOnly を実装することになります。そのため、プロパティを設定するには、実際に IReadWrite にダウンキャストする必要があります。

その問題を回避する別のアプローチですが、実装クラスとその呼び出し元にもう少しロジックが必要です。

Public Interface ISometimesWritable
    Property Name() As String
    ReadOnly Property AllowNameEdit() As Boolean
End Interface

Public Class ReadOnlyClass
    Implements ISometimesWritable

    Public ReadOnly Property AllowNameEdit() As Boolean Implements ISometimesWritable.AllowNameEdit
        Get
            Return False
        End Get
    End Property

    Private _Name As String
    Public Property Name() As String Implements ISometimesWritable.Name
        Get
            Return _Name
        End Get
        Set(ByVal value As String)
            Throw New NotSupportedException("Name cannot be set when AllowNameEdit is False")
        End Set
    End Property
End Class

Public Class ReadWriteClass
    Implements ISometimesWritable

    Public ReadOnly Property AllowNameEdit() As Boolean Implements ISometimesWritable.AllowNameEdit
        Get
            Return True
        End Get
    End Property

    Private _Name As String
    Public Property Name() As String Implements ISometimesWritable.Name
        Get
            Return _Name
        End Get
        Set(ByVal value As String)
            _Name = value
        End Set
    End Property
End Class

更新: ダウンキャストに関する質問に答えるには; 「ダウンキャスト」は、オブジェクトをスーパークラス、インターフェース、または抽象基本クラスTypeからより具体的な にキャストすることを説明するために使用される用語Typeです。

たとえば、上記の最初の例では、 と の 2 つのインターフェイスを定義していIReadOnlyますIReadWriteIReadWriteこれは、 と を実装するオブジェクトを呼び出すことIReadOnlyができることを意味します。IReadWrite IReadOnlyIReadWrite

IReadWriteimplementsは (の「サブクラス」IReadOnlyIReadWriteあると言われていますが、「サブクラス」は、インターフェイスを実装するのではなく、基本クラスを継承IReadOnlyするクラスを表すためにより正確に使用されますが、単純にするために、それらは非常にほぼ同じコンセプト)。が のサブクラスである場合、逆は真です。は のスーパークラスです。IReadWriteIReadOnlyIReadOnlyIReadWrite

たとえば、次ReadWriteClassのいずれかのインターフェイスの実装として のインスタンスを記述できます。

Public Sub SomeMethod()
    dim readOnlyInstance as IReadOnly = new ReadWriteClass()
    Console.WriteLine(readOnlyInstance.Name)

    ' The following line won't compile, since we're communicating with ReadWriteClass as an instance of IReadOnly
    'readOnlyInstance.Name = "Santa Clause"

    ' Here we downcast the variable to reference it by it's other interface, IReadWrite
    dim readWriteInstance = DirectCast(readOnlyInstance, IReadWrite)

    ' Now we can both Get and Set the value of Name
    readWriteInstance.Name = "John Doe"
    Console.WriteLine(readWriteInstance.Name)

    ' Note that in the above example we created *one* instance of ReadWriteClass
    ' and have provided two variables / references to the same underlying object.
    Console.WriteLine(readOnlyInstance.Name) ' <-- note that this should return "John Doe"

End Sub
于 2009-08-25T21:35:48.457 に答える