装饰设计 - 选项严格禁止缩小

时间:2014-07-28 15:09:05

标签: .net

我通过设计模式书工作,只是不能回复装饰类的例子。我试过示例1by1这里是示例(shortend):

Public Interface TakeHomePay
Function GetTakeHomePay() As Double 
End Interface

Public Class Employee : Implements TakeHomePay
Private m_GrossWage As Double
Private m_NetWage As Double
Public Function GetTakeHomePay() As Double Implements TakeHomePay.GetTakeHomePay
    Return m_NetWage
End Function End Class

Public MustInherit Class WageAdjustment : Implements TakeHomePay
Protected m_TakeHomePay As TakeHomePay
Public Sub New(ByRef thp As TakeHomePay)
    m_TakeHomePay = thp
End Sub
Public Function GetTakeHomePay() As Double Implements TakeHomePay.GetTakeHomePay
    Return m_TakeHomePay.GetTakeHomePay
End Function 
End Class

Public Class CountryTax : Inherits WageAdjustment
Private m_CountryName As String

Public Sub New(ByRef thp As TakeHomePay, ByVal CountryName As String)
    MyBase.New(thp)
    m_CountryName = CountryName
End Sub

Public Sub DeductTax()
    'something
End Sub End Class

employee类是具体类,WageAdjustment类是装饰器类,CountryTax类是装饰器子类。我的问题是,一旦我尝试在我的客户端使用它,如

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim objEmployee As New Employee
    Dim objCountryTax As CountryTax
    objCountryTax = New CountryTax(objEmployee, "USA")
End Sub
objEmployee”行中的

objCountryTax = New CountryTax(objEmployee, "USA")给出了错误:

  

“Option Strict On禁止从类型'TakeHomePay'缩小到类型   'Employee'将ByRef参数thp'的值复制回   匹配参数“

MSDN表示ByRef Paramenter(thp)的反向转换正在缩小。我只是看不到,为什么对象(基于界面)缩小(也许我只是没有得到缩小的定义虽然...)根据书这应该工作完美但这本书是8岁,所以也许那里在vs或.NET中有一些变化。我正在使用vs 2012.有谁可以告诉我为什么这不起作用以及我如何才能使它工作?

1 个答案:

答案 0 :(得分:3)

没有必要依赖一本8岁的书。您可以在线找到更多最新的装饰器模式示例,例如here

这是一个缩小转换的原因是被调用的构造函数的签名是:

Public Sub New(ByRef thp As TakeHomePay, ByVal CountryName As String)

你用

来称呼它
objCountryTax = New CountryTax(objEmployee, "USA")

由于第一个参数是ByRef,因此允许构造函数重新分配您传递的objEmployee引用。该重新分配将反映在objEmployee

但是objEmployee被声明为Employee类型,但构造函数只知道它是TakeHomePay实例。因此构造函数可以尝试将其重新分配为:

thp = New SomeOtherClassThatImplementsTakeHomePay()

该任务将传播到objEmployee。但是你不能把这个新对象塞进Employee引用中,因为前者可能无法分配给后者。

除非参数的具体原因为ByRef,否则将其更改为ByVal可以解决问题。问题是ByRefthp参数复制回objEmployee参考中引起的。