【问题标题】:Optional Readonly Property in VB.Net InterfaceVB.Net 接口中的可选只读属性
【发布时间】:2010-11-22 19:12:56
【问题描述】:

我正在尝试开发一个简单的界面,以允许从类中生成快速列表。基本上,接口需要返回一个 ID 和一个 Name。但是,一些类有一个只读的计算名称属性,其他类只使用读/写名称属性。基本上,我只关心它有一个 getter,属性是否有一个 setter 并不重要。如何编写此接口来处理或不引发编译错误?

我已经阅读了this question 并没有真正关注它,也许我只是很密集。如果是这样,请告诉我我的方式的错误:)

【问题讨论】:

    标签: vb.net interface properties readonly optional


    【解决方案1】:

    看起来另一个问题的答案会起作用:这是一个示例:

    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

    例如,上面的第一个示例定义了两个接口:IReadOnlyIReadWrite。您会注意到IReadWrite 实现了IReadOnly,这意味着您可以同时对实现IReadWrite 的对象进行IReadWriteIReadOnly 调用。

    由于IReadWrite 实现了IReadOnly,因此IReadWrite 被称为IReadOnly 的“子类”(尽管“子类”更准确地用于描述继承 一个基类,而不是 实现 一个接口——为了简单起见,它们几乎是相同的概念)。如果IReadWriteIReadOnly 的子类,则反之亦然——IReadOnlyIReadWrite超类

    例如,我可以将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
    

    【讨论】:

    • @foson:哎呀!让我重写它:)
    • 感谢代码,抱歉这么晚才回复。你能给我一个例子,说明何时以及如何实施向下转换,作为一个新手,这对我来说是新的。谢谢。
    • 扩展了一个例子。您应该阅读有关铸造主题的内容;阅读有关 CType()DirectCast()TryCast() 的 MSDN 文章和其他问题。
    • 这很详细,非常有帮助。谢谢!
    猜你喜欢
    • 2010-09-19
    • 2013-01-15
    • 2019-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-12
    • 2016-08-27
    • 2021-12-14
    相关资源
    最近更新 更多