问题是如何使用 LINQ 最终 Lambda 呈现 DispList 和 RotateList 函数的良好工作代码。提前谢谢
Class CalcProc
Property Year As Integer
Property Type As String
Property Count As Integer
Property Total As Integer
Property Proc As Decimal
End Class
Sub CreateListOfT()
Dim List As New List(Of CalcProc)
List.Add(New CalcProc With {.Year = 2013, .Type = "A", .Count = 12, .Total = 20, .Proc = calcP(.Count, .Total)})
List.Add(New CalcProc With {.Year = 2013, .Type = "B", .Count = 22, .Total = 30, .Proc = calcP(.Count, .Total)})
List.Add(New CalcProc With {.Year = 2014, .Type = "C", .Count = 32, .Total = 40, .Proc = calcP(.Count, .Total)})
List.Add(New CalcProc With {.Year = 2015, .Type = "D", .Count = 42, .Total = 50, .Proc = calcP(.Count, .Total)})
List.Add(New CalcProc With {.Year = 2016, .Type = "E", .Count = 52, .Total = 60, .Proc = calcP(.Count, .Total)})
DispListOfT(List)
RotateListOfT(List)
End Sub
Private Function DispListOfT(Of T)(ByVal dList As IList(Of T))
If Not dList.Any Then
MsgBox("NOTHING to display!", vbCritical, MethodBase.GetCurrentMethod.Name())
End
End If
Dim fields() = dList.First.GetType.GetProperties
Dim ListColumns = (From x In fields Select x.Name).ToList()
Console.WriteLine(String.Join(",", ListColumns.ToArray))
Dim sb As New Text.StringBuilder
For Each item In dList
sb.Length = 0
For Each field In fields
Dim p = item.GetType.GetProperty(field.Name)
sb.Append(p.GetValue(item, Nothing)) : sb.Append(",")
Next
Console.WriteLine(Left(sb.ToString, sb.Length - 1))
Next
End Function
Public Function RotateListOfT(Of T)(ByVal dList As IList(Of T))
Dim sa As New Text.StringBuilder
Dim fields() = dList.First.GetType.GetProperties
Dim dCount As Integer
Dim Modulo As Integer = dList.Count \ 4
For i As Integer = 0 To Modulo - 1
For Each field In fields
sa.Append(field.Name)
sa.Append(vbTab)
For Each item In dList
If dCount Mod Modulo = i Then
Dim p = item.GetType.GetProperty(field.Name)
sa.Append(p.GetValue(item, Nothing))
sa.Append(vbTab)
End If
dCount += 1
Next
Console.WriteLine(sa.ToString)
sa.Length = 0
Next
Next
End Function
Function calcP(a As Integer, b As Integer) As Decimal
Return Round(a * 100.0 / b, 2)
End Function
List(Of T)
Year, Type, Count, Total, Proc
2013,A,12,20,60
2013,B,22,30,73.33
2014,C,32,40,80
2015,D,42,50,84
2016,E,52,60,86.67
已旋转List(Of T)
Year 2013 2013 2014 2015 2016
Type A B C D E
Count 12 22 32 42 52
Total 20 30 40 50 60
Proc 60 73.33 80 84 86.67
答案 0 :(得分:2)
以下是我对Sub
的重写。虽然您可以使用For Each
替换剩余的List.ForEach
循环,但这样做没有任何优势,我认为它不太清楚。 LINQ非常适合将序列转换为结果,然后将其用于I / O.
由于您知道参数dList
是IList(Of T)
,因此您知道T
的每个成员都具有相同的属性,因此没有理由检索每个项目的属性。
最后我使用lambda语法作为LINQ,因为它有助于嵌套在其他函数调用中。
Public Sub DispListOfT(Of T)(ByVal dList As IList(Of T))
If Not dList.Any Then
'MsgBox("NOTHING to display!", vbCritical, MethodBase.GetCurrentMethod.Name())
Return
End If
Dim props = dList.First.GetType.GetProperties
Console.WriteLine(String.Join(",", props.Select(Function(p) p.Name)))
For Each item In dList
Console.WriteLine(String.Join(",", props.Select(Function(p) p.GetValue(item))))
Next
End Sub
Public Sub RotateListOfT(Of T)(ByVal dList As IList(Of T))
For Each prop In dList.First.GetType.GetProperties
Console.Write(prop.Name)
Console.Write(vbTab)
Console.WriteLine(String.Join(vbTab, dList.Select(Function(item) prop.GetValue(item))))
Next
End Sub
如果我正在编写一个程序来执行此操作,我可能会将List
的旋转与输出旋转的List
分开。此外,使用Reflection从类型中获取属性名称应该是非常不寻常的,您应该已经知道要处理的类型并将输出方法添加到类的类中,除非您的程序处理大量不同的列表因某种原因而上课。