65.9K
CodeProject 正在变化。 阅读更多。
Home

几乎是扩展属性

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2016 年 3 月 25 日

CPOL

2分钟阅读

viewsIcon

16748

downloadIcon

76

如何模拟扩展属性…

引言

扩展方法(FunctionSub)是一种强大的工具,可以扩展原本密封的对象。它比创建 Class 扩展更容易,因为你不需要更新你的代码(可能已经部署),例如将 Dim nice As SomeClass 更改为 Dim nice As SomeClassExtendedAndNicer。 显然,不同的情况需要不同的解决方案,你可能需要一个扩展的 Class,但如果我可以使用扩展方法解决问题,我更喜欢使用扩展方法。扩展方法的一个巨大缺点是,你无法编写扩展属性!请参阅 MSDN 此处

在本技巧中,我将展示如何(滥)用 Tag 属性作为扩展属性或 AlmostExtensionProperty 的代理。这个技巧的灵感来自于 StackOverflow 上的一个问答:VB extension property instead of extension method

代码示例

首先,我们需要一个 Class 作为一些额外的扩展属性的容器。 你会为 ExtendedClass 或类似 AlmostExtensionProperty 编写这个 Class

Public Class ExtendedProps
    Public StrA As String = "A"
    Public DblB As Double = 2
    Public BoolC As Boolean = True
    
    'etc...
    
End Class

我将使用 Forms Label 控件作为示例,使用 ExtendedClass 你可以编写如下代码

Public Class ExtendedLabel
    Inherits Label
    
    Public Sub New()
        MyBase.New
        _extProps = New ExtendedProps
    End Sub
    
    Private _extProps As ExtendedProps = Nothing
    
    Public Property ExtraProperties() As ExtendedProps
        Get
            Return _extProps
        End Get
        Set
            _extProps = value
        End Set
    End Property
End Class

到目前为止,没什么新鲜的。现在,创建一个 AlmostExtensionProperty 需要一个 Extension Module 并(滥)用 Label 控件的 Tag 对象,如下所示

Imports System.Runtime.CompilerServices
Public Module Extensions
    <Extension()>
    Public Function GetMoreProps(ByVal thisLabel As Label) As ExtendedProps
        Try
            Return CType(thisLabel.Tag,ExtendedProps)
        Catch
            Return Nothing
        End Try
    End Function
    
    <Extension()>
    Public Function SetMoreProps(ByVal thisLabel As Label, extraProps As ExtendedProps) As Boolean
        Try
            thisLabel.Tag = extraProps
            Return True
        Catch
            Return False
        End Try
    End Function
End Module

两个扩展方法,通过 Label 控件的 Tag 对象暴露 ExtendedProps 类,这就是你所需要的。现在,如果你创建一个包含两个标签的窗体(一个常规 System.Windows.Forms.Label 和另一个特殊的 ExtendedLabel),你可以测试 ExtendedProps

Public Class Main 'form
    Public Sub New()
        'Just a form with two Label controls:
        'Dim labExtendedLabelClass As New ExtendedLabel()
        'Dim labAlmostPropExt As New Label()
        'Me.InitializeComponent()
        
        labAlmostPropExt.SetMoreProps(New ExtendedProps)
        Debug.Print("Property StrA from a Label with an AlmostPropertyExtension = " & _
                     labAlmostPropExt.GetMoreProps.StrA)
        
        Debug.Print("Property StrA from a Label extended class = " & _
                     labExtendedLabelClass.ExtraProperties.StrA)
        
    End Sub
End Class

运行此窗体将给出以下输出

Property StrA from a Label with an AlmostPropertyExtension = A
Property StrA from a Label extended class = A

不同的方法,相似的结果。

关注点

确实,这可能是 Tag 属性不太常用的用法。但是,对于所有不当编码的指责,我将回答:“谁告诉你编码世界是规范的……?”

历史

  • 2016年3月25日:首次发布
© . All rights reserved.