【问题标题】:How to extend/decorate third-party classes in VB.NET?如何在 VB.NET 中扩展/装饰第三方类?
【发布时间】:2012-07-06 18:50:22
【问题描述】:

在 Ruby 中,所有的类都是永远开放的。几乎任何时候都可以将新行为添加到任何类中。有没有办法在 VB.NET 中做到这一点?

例如,如果我希望现有应用程序(大型应用程序)中的所有 DataRows 都采用新行为,该怎么办。我意识到我可以创建一个从 DataRow 继承的自定义行类,但继承不是我所追求的。这将涉及大量返工,以确保在所有地方都实例化行,我们是从我们的自定义行类中实例化的。

关于如何做到这一点,我有两个粗略的想法:

  1. 我突然想到方面 (AOP) 可以在这里工作。 Is there a way to layer behavior on top of existing methods?

  2. 是否可以申请a given Interface to existing classes

这里的主要目标是不必对现有代码进行任何大型改造。系统实际上应该忽略这些分层的行为/方面。它应该对代码库进行最小的更改。

目前,我们使用装饰器类实现分层方面。问题是,系统知道本地行和行装饰器对象之间的区别。我希望能够传递系统认为是本机行的东西。同样,系统不需要注意应用于行的装饰。它应该认为它有一行,而不是一些特殊的装饰器。

具体来说,我想装饰一行的默认 set Item(colName) 属性,以便我可以修改传入的值。

【问题讨论】:

  • 我遇到的一个问题是 VB.NET 没有对方面的原生支持。我发现了许多 AOP 框架。 IMO,语言应该原生支持添加方面。
  • 正确,您只能在 .Net 中使用带有框架的 AOP,例如PostSharp。或者微软的Unity应用程序块eg

标签: vb.net interface metaprogramming aop decorator


【解决方案1】:

您所要求的大部分内容都可以通过扩展方法实现。请参阅此处了解更多信息:

http://msdn.microsoft.com/en-us/library/bb384936.aspx

这是该链接中的一个示例,它将 Print 方法添加到所有 String 对象:

Module StringExtensions
    <Extension()> 
    Public Sub Print(ByVal aString As String)
        Console.WriteLine(aString)
    End Sub
End Module

但是,您只能使用扩展方法来添加方法,而不是属性或字段。此外,您只能添加新方法或重载。您不能用新方法覆盖现有方法。

由于您所说的具体是覆盖类的索引器属性的能力,因此扩展方法在这种情况下对您没有帮助。我知道的唯一其他选择是欺骗您的项目使用您的包装类而不是真实的。您可以创建自己的库,该库在与您尝试扩展的任何库相同的命名空间中实现具有相同名称的相同类。您的包装库将引用真实的,并从原始的继承所有类。然后,您可以随心所欲地扩展它们,而您的其他项目可以简单地引用您的库而不是真正的库。为此,您当然需要使用大量命名空间别名和很可能的程序集引用别名(这在 VB.NET 中不可用,因此您可能必须用 C# 编写库,它支持 extern关键词)。但我怀疑这对你来说可能不值得。

【讨论】:

  • 我广泛使用扩展方法。不幸的是,它们不允许任何形式的装饰。 DataRow 有一个默认属性:Item。我想拦截到 Item setter 的消息。例如,在 Ruby 中,使用一行代码,我可以轻松地记录行属性的设置以调试某些内容,并在完成后删除该行代码。这里的关键是能够通过几行代码轻松添加或删除行为,而不是进行大规模的重构。
猜你喜欢
  • 1970-01-01
  • 2014-07-31
  • 1970-01-01
  • 1970-01-01
  • 2021-07-07
  • 2020-11-13
  • 1970-01-01
  • 2020-05-20
  • 2017-04-02
相关资源
最近更新 更多