代码之家  ›  专栏  ›  技术社区  ›  Stan

使用继承对象类型时传递基对象类型

  •  4
  • Stan  · 技术社区  · 14 年前

    我有一个项目,主要有两个对象,都是从一个基继承的。这样地:

    Public Class Vehicle
        Property Model As String
        Property Make As String
    End Class
    
    Public Class Truck
        Inherits Vehicle
        Property IsFlatbed As Boolean
    End Class
    
    Public Class Car
        Inherits Vehicle
        Property LeatherSeats As Boolean
    End Class
    

    很简单,嗯?因为我不知道用户是否会选择汽车或卡车,所以我想做的只是四处转转 Vehicle .

    所以,就像这样:

    Public v As Vehicle
    Sub WhichVehicle()
        Select Case cmbVehicle.SelectedItem
            Case Truck
                v = New Truck
            Case Car
                v = New Car
        End Select
        SetFlat (v)
    End Sub
    

    这一切都行,但现在我只想通过 v 使用它的属性。比如:

    Sub SetFlat (myVehicle As Vehicle)
        myVehicle.IsFlatbed = True
    End Sub
    

    myVehicle 车辆 ,不是 Truck .

    有没有办法让我绕过 车辆

    5 回复  |  直到 14 年前
        1
  •  2
  •   smirkingman    14 年前

    这是实现这一目标的一种方法:

    Imports System.Reflection
    Module main_
        Sub Main()
            Dim t As New Truck
            Dim c As New Car
            Dim v As Vehicle
            v = t
            SetFlat(v)
            v = c
            SetFlat(v)
        End Sub
        Sub SetFlat(ByVal v As Vehicle)
    
            Dim vehicletype As Type
            Dim members() As PropertyInfo
    
            vehicletype = v.GetType
            members = vehicletype.GetProperties
    
            Console.Write("v is a " & vehicletype.ToString)
            For Each m As PropertyInfo In members
                If m.Name = "IsFlatbed" Then
                    m.SetValue(v, True, Nothing)
                    Console.WriteLine(" and now it's a flatbed")
                    Exit Sub
                End If
            Next
            Console.WriteLine(" so flatbed doesn't apply")
        End Sub
    End Module
    

    v is a Vehicles.Truck and now it's a flatbed
    v is a Vehicles.Car so flatbed doesn't apply
    
        2
  •  3
  •   GôTô    14 年前

    SetFlat IsFlatbed ,对吧?

    那么你应该声明一个接口 Flattable Truck 将实现该接口,并且 刚毛 潜艇会有一个 平板

    编辑:

    Public Interface IFlattable
        Property IsFlatbed() As Boolean
    End Interface
    
    Public Class Truck
        Inherits Vehicle
        Implements IFlattable
    
        Private _isFlatBed as Boolean
        Public Property IsFlatbed() as Boolean Implements IFlattable.IsFlatbed
            Get
                Return _isFlatbed
            End Get
            Set(ByVal value as Boolean)
                _isFlatbed = value
            End Set
    End Class
    
    
    Public v As Vehicle
    Sub WhichVehicle()
        Select Case cmbVehicle.SelectedItem
            Case Truck
                v = New Truck
                SetFlat (DirectCast(v, IFlattable))
            Case Car
                v = New Car
        End Select
    End Sub
    
    Sub SetFlat (myVehicle As Flattable)
        myVehicle.IsFlatbed = True
    End Sub
    
        3
  •  2
  •   Community CDub    8 年前

    我找到了两种可能对你有帮助的方法。

    它可能看起来像(我不是VB.Net程序员,所以可能有一些错误):

    Sub SetFlat(of T) (myVehicle As T)
        T.IsFlatbed = True
    End Sub
    // later you can just call
    SetFlat(Of Truct)(myVehicle)  
    

    当然这意味着您需要在调用之前知道myVehicle对象的确切类型 SetFlat函数。同时,SetFlat只能与具有isflated属性的类一起调用。 有关VB.Net中泛型的更多详细信息:
    http://www.15seconds.com/issue/040526.htm
    http://msdn.microsoft.com/en-us/library/w256ka79%28VS.80%29.aspx
    Generic Functions in VB.NET

    第二个(脏)解决方案是使用.Net反射来检测myVehicle对象是否包含IsFlatbed属性。您可以在以下方面找到更多详细信息:
    http://msdn.microsoft.com/en-us/magazine/cc163750.aspx
    http://visualbasic.about.com/od/usingvbnet/a/proginfo.htm
    http://www.eggheadcafe.com/community/aspnet/14/14989/reflection.aspx

        4
  •  2
  •   Cody Gray    14 年前

    我决定启动Visual Studio并进行一些测试,因为我对其他答案的评论可能没有多大意义。假设您有以下类:

    Public Class Vehicle
       Public Property Model As String
       Public Property Make As String
    End Class
    
    Public Class Truck : Inherits Vehicle
       Public Property IsFlatbed As Boolean
    End Class
    
    Public Class Car : Inherits Vehicle
       Public Property LeatherSeats As Boolean
    End Class
    

    您还可以在另一个类中使用以下方法:

    Private Sub WhichVehicle()
        Select Case cmbVehicle.SelectedItem
            Case Truck
                v = New Truck
            Case Car
                v = New Car
        End Select
    
        SetFlat(v)
    End Sub
    
    Private Sub SetFlat(ByVal myVehicle As Vehicle)
       If TypeOf myVehicle Is Car Then
          Debug.WriteLine("This is a car")
    
          Dim c As Car = DirectCast(myVehicle, Car)
          c.LeatherSeats = False
       ElseIf TypeOf myVehicle is Truck Then
          Debug.WriteLine("This is a truck")
    
          Dim t As Truck = DirectCast(myVehicle, Truck)
          t.IsFlatbed = True
       End If
    End Sub
    

    所以,这可以让你随心所欲地绕过一个车辆对象,因为直到运行时,你才知道你要处理的具体车辆类型(汽车或卡车)。SetFlat方法可以在运行时确定它通过了哪个特定的车辆子类,并相应地采取行动。您只需确保在确定泛型车辆对象(v)是哪种类型的子类(对于Car是c,对于Truck是t)之后,将泛型车辆对象(v)转换为更具体的子类的新对象,否则代码将不会编译,因为您将尝试调用泛型车辆类型上不存在的方法,但仅限于特定车型。

    我看到这种方法最大的缺点是,如果有很多代码,它可能会变得乏味。这是因为要调用的每个方法都必须检查传递给它的特定vehicle对象的类型,并根据该特定类型运行一组不同的例程。

        5
  •  0
  •   jaraics    14 年前

    我认为你应该提供更多的细节关于你想做什么。。。 typeof

    Dim v as Vehicle
    '...
    If typeof v is Truck then SetFlat(DirectCast(v, Truck))
    

    编辑 :SetFlat应该以Truck作为参数,只有这样才有意义。