Vb.net 防止将继承的对象传递给共享函数

Vb.net 防止将继承的对象传递给共享函数,vb.net,inheritance,Vb.net,Inheritance,我有一个非常做作的例子来解释我的业务对象如何加载它们的数据。但是,我想防止出现下面所示的情况。我知道这里有缺点,但它就是这样(到目前为止)!如何在不重构接口等的情况下实现这一点 Public Class Car Public Property Passengers As Integer Public Shared Sub Fill(c As Car, r As SqlDataReader) Passengers = r.GetInt32(0) End Sub End C

我有一个非常做作的例子来解释我的业务对象如何加载它们的数据。但是,我想防止出现下面所示的情况。我知道这里有缺点,但它就是这样(到目前为止)!如何在不重构接口等的情况下实现这一点

Public Class Car

  Public Property Passengers As Integer

  Public Shared Sub Fill(c As Car, r As SqlDataReader)
    Passengers = r.GetInt32(0)
  End Sub

End Class

Public Class UsedCar
  Inherits Car

  Public Property PreviousOwner As String

  Public Shared Sub FillUsed(l As Limo, r As SqlDataReader)
    Passengers = r.GetInt32(0)
    PreviousOwner = r.GetString(1)
  End Sub

End Class

Public Sub CreateVehicles()

  Dim c As New Car()
  Car.FillWithStuff(c, GetSqlReader(carId))

  Dim l As New UsedCar()
  UsedCar.FillUsed(l, GetSqlReader(usedCarId)) 'Great
  Car.Fill(l, GetSqlReader(usedCarId)) 'No! << Stop this at once!
  UsedCar.Fill(l, GetSqlReader(usedCarId)) '<<< Even more wrong!

End Sub
公车
公共财产乘客为整数
公共共享子填充(c为汽车,r为SqlDataReader)
乘客=r.GetInt32(0)
端接头
末级
公共类使用的CAR
继承汽车
公共属性PreviousOwner作为字符串
使用公共共享子文件(l作为Limo,r作为SqlDataReader)
乘客=r.GetInt32(0)
PreviousOwner=r.GetString(1)
端接头
末级
公共交通工具()
尺寸c为新车()
用凝灰岩填充汽车(c,GetSqlReader(carId))
尺寸l为新使用的车辆()
FillUsed(l,GetSqlReader(usedcard))'太棒了

Car.Fill(l,GetSqlReader(UsedCrand))'不 除了抛出一个异常之外,没有办法要求这样做。例如:

Public Shared Sub FillWithStuff(c As Car)
    If Not (TypeOf c Is Car) Then
        Throw New Exception("Must be a Car")
    End If
    Passengers = 4
End Sub

然而,您提供的简化示例并不能充分解释为什么在您的情况下,豪华轿车不是有效的汽车。如果,事实上,它不是一个有效的汽车,那么它不应该继承自汽车。很可能您的代码应该进行重构,以便car和limo是两个不相关的类,它们共享相同的依赖项业务类以实现公共功能。

将构造函数设为私有,并让各种Fill()方法实例化并返回一个全新的对象,或者您可以移动Fill()将代码写入构造函数本身。由于方法与数据库结果紧密相关,另一种选择是将构造函数标记为“Friend”,并将Fill()方法移动到与数据层一起使用的单独模块中


这里的目标是,创建汽车的唯一方法是使用定义的工厂方法,该方法能够在编译时检查适当的类型是否匹配。

Limo.FillWithStuff
更糟糕……我感觉你是对的。该死的利斯科夫和他的校长!也许我的暴力方法不是最好的,所以合成看起来是目前最好的选择…抱歉,这不是最好的例子。所讨论的实际方法将从
SqlDataReader
填充对象。“豪华轿车”实际上相当于一辆二手车,因此它将拥有一个“原车主”财产。也许我应该把我的例子改成。。。