【问题标题】:How can I process lists of different generic type?如何处理不同泛型类型的列表?
【发布时间】:2016-01-01 11:04:30
【问题描述】:

我写了以下代码:

Public Class FrmMain
    Private Sub FrmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        '''''''''BioSystem Section'''''''''
        Dim Bio As New BioSystem
        Dim LstBioSystem As New List(Of BioSystem)

        Bio.Heart = "Some Value"
        Bio.liver = "Some Value"
        Bio.Lungs = "Some Value"
        LstBioSystem.Add(Bio)
        '''''Add Second Value to BioSystem list
        Bio = New BioSystem
        Bio.Heart = "Some Value2"
        Bio.liver = "Some Value2"
        Bio.Lungs = "Some Value2"
        LstBioSystem.Add(Bio)

        '''''''''Car Section'''''''''
        Dim Car As New CarSystem
        Dim LstCars As New List(Of CarSystem)

        Car.Acceleration = "Some Value"
        Car.Engine = "Some Value"
        Car.Speed = "Some Value"
        Car.Weight = "Some Value"
        LstCars.Add(Car)
        '''''Add Second Value to Car list
        Car = New CarSystem
        Car.Acceleration = "Some Value2"
        Car.Engine = "Some Value"
        Car.Speed = "Some Value2"
        Car.Weight = "Some Value2"
        LstCars.Add(Car)

        ''''Output values
        WriteBio(LstBioSystem)
        WriteCar(LstCars)
    End Sub

    Public Sub WriteBio(ByVal BioList As List(Of BioSystem))
        For Each Bio As BioSystem In BioList
            Console.WriteLine($"Heart:{Bio.Heart}, liver:{Bio.liver}, Lungs:{Bio.Lungs}")
        Next
    End Sub

    Public Sub WriteCar(ByVal CarList As List(Of CarSystem))
            For Each Car As CarSystem In CarList
                Console.WriteLine($"Acceleration:{Car.Acceleration}, Engine:{Car.Engine}, Speed:{Car.Speed}, Weight:{Car.Weight}")
            Next
    End Sub
End Class

Public Class BioSystem
    Public Property Heart As String
    Public Property liver As String
    Public Property Lungs As String
End Class

Public Class CarSystem
    Public Property Engine As String
    Public Property Speed As String
    Public Property Acceleration As String
    Public Property Weight As String
End Class

我想知道是否有办法简化代码?

做这样的事情:

*Method "WriteStr" 应该替换 "WriteBio" 方法和"WirteCar" 方法。

'using:

  WriteStr(LstBioSystem)
  WriteStr(LstCars)

''''
      Public Sub WriteStr(Of T)(ByVal Lst As List(Of T))
            Select Case GetType(T)
                Case GetType(BioSystem)
                    For Each Bio As BioSystem In Lst
                        Console.WriteLine($"Heart: {Bio.Heart}, liver:{Bio.liver}, Lungs:{Bio.Lungs}")
                Next
            Case GetType(CarSystem)
                For Each Car As CarSystem In Lst
                    Console.WriteLine($"Acceleration:{Car.Acceleration}, Engine:{Car.Engine}, Speed:{Car.Speed}, Weight:{Car.Weight}")
                Next
        End Select
    End Sub

当然,我有错误;

“'T' 类型的值无法转换为 'BioSystem'”

“'T' 类型的值不能转换为 'CarSystem'”

【问题讨论】:

  • 你可以使用List(Of Object)
  • 你的 Car 和 Bio 可以覆盖 ToString,那么不管是什么类型
  • 如果将其更改为对象,我得到了错误。 Visual Studio 建议在“WriteStr”方法中更改“IEnumerable”,而不是使用列表,它的工作,但我应该了解更多关于“IEnumerable”的信息?我需要使用这种方式。覆盖我的观点..
  • 您的BioSystem 和CarSystem 类彼此没有共同点。更改为 List(Of Object) 并为它们覆盖 ToString() 将是最简单的解决方案。如果你想强迫他们有共同点,那就开发一个他们都必须实现的Interface,然后改为List(Of YourInterfaceType)。

标签: vb.net list types type-conversion


【解决方案1】:

你应该重写你的类自动继承自Object的ToString方法

Public Class BioSystem
    Public Property Heart As String
    Public Property Liver As String
    Public Property Lungs As String

    Public Overrides Function ToString() As String
        Return $"Heart: {Heart}, Liver: {Liver}, Lungs: {Lungs}"
    End Function
End Class

Public Class CarSystem
    Public Property Engine As String
    Public Property Speed As String
    Public Property Acceleration As String
    Public Property Weight As String

    Public Overrides Function ToString() As String
        Return $"Acceleration: {Acceleration}, Engine: {Engine}, Speed: {Speed}, Weight: {Weight}"
    End Function
End Class

使用这些声明,您可以简单地编写:

Console.WriteLine(bio)

或

Console.WriteLine(car)

你可以编写一个适用于任何类型列表的方法

Public Sub WriteList(Of T)(list As List(Of T))
    For Each item As T In list
        Console.WriteLine(item)
    Next
End Sub

您可以使用对象和集合初始化器来简化对象和列表的创建。

Dim bioSystems = new List(Of BioSystem) From {
    New BioSystem() With { .Heart =  "heart 1", .Liver =  "liver 1", .Lungs = "lung 1" },
    New BioSystem() With { .Heart =  "heart 2", .Liver =  "liver 2", .Lungs = "lung 2" }
}
WriteList(bioSystems)

输出:

心脏:心脏 1,肝脏:肝脏 1,肺:肺 1
心脏:心脏 2,肝脏:肝脏 2,肺:肺 2

见:https://dotnetfiddle.net/YkE9Nz


结论:Select Case-statements 通常强烈暗示事情不是以最佳的面向对象方式完成的。让对象做自己的事情,而不是在这些对象之外的 select-case-statement 中做这些事情。在上面的示例中,每个对象都负责创建自己的字符串表示形式。

见:
- Inheritance and Polymorphism in VB.NET
- Replace Conditional with Polymorphism(C# 但很好的解释)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 2020-08-15
    • 2018-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多