传递包含重载属性作为参数的派生类

时间:2019-07-01 18:59:15

标签: vb.net

我有两个对象,一个是基类,另一个是继承基类的派生类。派生类上的属性之一使基类上的属性重载。现在,我想通过将这两个对象作为参数传递给函数来对这两个对象进行一些计算。问题是,如果我将此函数的参数定义为基类,则在传递派生类时,重载属性的值会丢失!

我使用派生类的原因是要临时添加更多属性/修改基类的现有属性以执行其他计算,以便重用基类。

我尝试了4种不同的功能,但它们都不是一件好事。它们要么不能正常工作,要么有重复的代码,我需要避免,因为以后会有更多的代码。下面是伪代码。

定义类:

Class BaseClass
    Public Property Name As String
    Public Property Value As Integer
End Class

Class DerivedClass
    Inherits BaseClass
    Overloads Property Value As Double
End Class

正在初始化:

Dim MyBaseObject As New BaseClass()
MyBaseObject.Name = NameOf(MyBaseObject)
MyBaseObject.Value = 5

Dim MyDerivedObject As New DerivedClass
MyDerivedObject.Name = NameOf(MyDerivedObject)
MyDerivedObject.Value = 5.3

调用函数:

ProcessClass1(MyBaseObject)
ProcessClass1(MyDerivedObject)

ProcessClass2(MyBaseObject)
ProcessClass2(MyDerivedObject)

ProcessClass3(MyBaseObject)
ProcessClass3(MyDerivedObject)

ProcessClass4(MyBaseObject)
ProcessClass4(MyDerivedObject)

功能:

Sub ProcessClass1(inClass As Object) 'functions correctly, but no intellisense
    Console.WriteLine(inClass.Name & " " & inClass.Value)
End Sub

Sub ProcessClass2(inClass As BaseClass) 'does not function correctly, but has intellisense
    Console.WriteLine(inClass.Name & " " & inClass.Value) 'Value displays 0 when passing MyDerivedObject, it should be 5.3!
End Sub

Sub ProcessClass3(inClass As Object) 'functions correctly, has intellisense, but need to write code for all possible derived types in advance

    If inClass.GetType = GetType(BaseClass) Then
        Dim inBaseClass As BaseClass = inClass
        Console.WriteLine(inBaseClass.Name & " " & inBaseClass.Value)
    End If

    If inClass.GetType = GetType(DerivedClass) Then
        Dim inDerivedClass As DerivedClass = inClass
        Console.WriteLine(inDerivedClass.Name & " " & inDerivedClass.Value)
    End If

End Sub

Sub ProcessClass4(inClass As BaseClass) 'method overloading: functions correctly, has intellisense, but need to write a duplicate method for every derived type
    Console.WriteLine(inClass.Name & " " & inClass.Value)
End Sub
Sub ProcessClass4(inClass As DerivedClass) 'method overloading: functions correctly, has intellisense, but need to write a duplicate method for every derived type
    Console.WriteLine(inClass.Name & " " & inClass.Value)
End Sub

附加:泛型 我看不到泛型的任何优势,下面的代码片段遇到了与ProcessClass2相同的问题:

Dim MyProcessGenericObject As New ProcessGenericClass(Of BaseClass)

MyProcessGenericObject.processNewItem(MyBaseObject)
MyProcessGenericObject.processNewItem(MyDerivedObject)

Public Class ProcessGenericClass(Of T As BaseClass)
    Public Sub processNewItem(ByVal newItem As T)
        Console.WriteLine(newItem.Name & " " & newItem.Value) 'Value displays 0 when passing MyDerivedObject!
    End Sub
End Class

在这四个函数中,ProcessClass1是最优雅的,代码量最少,但是inClass上没有智能感知,因此无法维护。

我需要的是没有代码重复,智能感知的方法,这种方法可以采用从相同基类继承的派生类,而又不会丢失任何重载属性中包含的数据。实现这一目标的最佳方法是什么?谢谢。

1 个答案:

答案 0 :(得分:1)

您提出的内容不适用于作为基类传递的实例。该实例的value属性将始终为整数,除非您能够将该实例转换为适当的派生类(并且(double)int转换是您失去精度的地方)。

但是将这些泛型中的一些结合使用可能会有所帮助。请注意,基类将不包含整数,而是一个对象。

Public Class BaseClass
    Public Property Name As String
    Public Property Value As Object
End Class

Public Class BaseClass(Of T)
    Inherits BaseClass
    Public Overloads Property Value As T
        Get
            Return CType(MyBase.Value, T)
        End Get
        Set(value As T)
            MyBase.Value = value
        End Set
    End Property
End Class

Class DerivedClassDouble
    Inherits BaseClass(Of Double)
End Class

Class DerivedClassInteger
    Inherits BaseClass(Of Integer)
End Class

处理方法

Sub ProcessClass(inClass As BaseClass)
    Console.WriteLine($"{inClass.Name} {inClass.Value}")
End Sub

一些实例化选项

Dim [myBase] As New BaseClass()
[myBase].Name = NameOf([myBase])
[myBase].Value = 5

Dim myBaseInteger As New BaseClass(Of Integer)
myBaseInteger.Name = NameOf(myBaseInteger)
myBaseInteger.Value = 5

Dim myDerivedInteger As New DerivedClassInteger
myDerivedInteger.Name = NameOf(myDerivedInteger)
myDerivedInteger.Value = 5

Dim myBaseDouble As New BaseClass(Of Double)
myBaseDouble.Name = NameOf(myBaseDouble)
myBaseDouble.Value = 5.3

Dim myDerivedDouble As New DerivedClassDouble
myDerivedDouble.Name = NameOf(myDerivedDouble)
myDerivedDouble.Value = 5.3

ProcessClass([myBase])
ProcessClass(myBaseInteger)
ProcessClass(myDerivedInteger)
ProcessClass(myBaseDouble)
ProcessClass(myDerivedDouble)

Console.ReadLine()
  

myBase 5   
myBaseInteger 5   
myDerivedInteger 5   
myBaseDouble 5.3   
myDerivedDouble 5.3

我认为与您的实现最接近的是使用[myBase]myDerivedDouble实例。然后将通用基类更改为Public MustInherit Class BaseClass(Of T)可以使意图更清晰。

希望最后一次编辑,对于冗长的回答感到抱歉。

您可以更改原始类以在基类中具有一个对象,并使用我布置的属性实现,这似乎可以在没有任何泛型的情况下完成工作。再说一次,它可能会或可能不会在您的确切实现中起作用

Sub Main()
    Dim MyBaseObject As New BaseClass()
    MyBaseObject.Name = NameOf(MyBaseObject)
    MyBaseObject.Value = 5

    Dim MyDerivedObject As New DerivedClass
    MyDerivedObject.Name = NameOf(MyDerivedObject)
    MyDerivedObject.Value = 5.3

    ProcessClass(MyBaseObject)
    ProcessClass(MyDerivedObject)

    Console.ReadLine()
End Sub

Sub ProcessClass(inClass As BaseClass)
    Console.WriteLine($"{inClass.Name} {inClass.Value}")
End Sub

Public Class BaseClass
    Public Property Name As String
    Public Property Value As Object
End Class

Public Class DerivedClass
    Inherits BaseClass
    Overloads Property Value As Double
        Get
            Return CDbl(MyBase.Value)
        End Get
        Set(value As Double)
            MyBase.Value = value
        End Set
    End Property
End Class
  

MyBaseObject 5   
MyDerivedObject 5.3