|
Public Class Article
Public ProductName As String
Public QuantityPerUnit As String
Public UnitPrice As Decimal
Public UnitsInStock As Short
Public Discontinued As Boolean
Public Shared Function GetRecords(ByVal TP As FileIO.TextFieldParser) As _
IEnumerable(Of Article)
Return New CsvEnumerable(Of Article)(TP)
End Function
End Class
Imports System.Reflection
Public Class CsvEnumerable(Of T As New) : Inherits Enumerable(Of T)
Private _TP As FileIO.TextFieldParser
Private Shared _Flds As FieldInfo() = _
GetType(T).GetFields(BindingFlags.Instance Or BindingFlags.Public)
Private Shared _Converters As System.ComponentModel.TypeConverter()
Shared Sub New()
Using Prov = New VBCodeProvider
_Converters = _Flds.Select(Function(fld As FieldInfo) _
Prov.GetConverter(fld.FieldType)).ToArray
End Using
End Sub
Public Sub New(ByVal TP As FileIO.TextFieldParser)
_TP = TP
End Sub
Protected Overrides Function TryMovenext(ByRef Current As T) As Boolean
TryMovenext = Not _TP.EndOfData
If TryMovenext Then
Current = New T
Dim Row As String() = _TP.ReadFields
For I = 0 To _Flds.Length - 1
_Flds(I).SetValue(Current, _
_Converters(I).ConvertFromString(Row(I)))
Next
End If
End Function
End Class
Imports System.Collections.Generic
Imports System.Collections
Public MustInherit Class Enumerable(Of T) : Implements IEnumerable(Of T)
Private _enrt As New Enumerator(Me)
Private _IsPrepared As Boolean
Protected MustOverride Function TryMovenext(ByRef Current As T) As Boolean
Protected Overridable Sub Prepare()
End Sub
Protected Overridable Sub CleanUp()
_IsPrepared = False
End Sub
Public Function GetEnumerator() As IEnumerator(Of T) _
Implements IEnumerable(Of T).GetEnumerator
If _IsPrepared Then Throw New Exception(String.Concat( _
"IEnumerable(Of ", GetType(T).Name, ") ", _
"kann nicht mehrere Enumeratoren gleichzeitig bereitstellen."))
Prepare()
_IsPrepared = True
Return _enrt
End Function
Private Function GetEnumerator1() As IEnumerator _
Implements IEnumerable.GetEnumerator
Return GetEnumerator()
End Function
Public Class Enumerator : Implements IEnumerator(Of T)
Private _Current As T = Nothing
Private _enmbl As Enumerable(Of T)
Public Sub New(ByVal enmbl As Enumerable(Of T))
_enmbl = enmbl
End Sub
Private ReadOnly Property Current() As T _
Implements IEnumerator(Of T).Current
Get
Return _Current
End Get
End Property
Private ReadOnly Property Current1() As Object _
Implements IEnumerator.Current
Get
Return _Current
End Get
End Property
Private Function MoveNext() As Boolean Implements IEnumerator.MoveNext
Return _enmbl.TryMovenext(_Current)
End Function
Private Sub Prepare() Implements IEnumerator.Reset
_enmbl.Prepare()
End Sub
Private Sub Dispose() Implements IDisposable.Dispose
_enmbl.CleanUp()
End Sub
End Class End Class
Imports System.IO
Imports System.Data
Imports System.Data.OleDb
Public Class frmIEnumerableOf
Private Animals As IEnumerable(Of String()) = _
Permutations.Of("ant bat cow dog".Split(" "c))
Private Sub Button_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles btAllPermutations.Click, btAntAsSecondMember.Click, _
btPriceOfAll.Click
Select Case True
Case sender Is btAllPermutations
Dim All = From P In Animals Select String.Join(" "c, P)
MsgBox(String.Join(NewLine, All.ToArray), , _
"Alle Permutationen")
Case sender Is btAntAsSecondMember
Dim AntsOnSecond = From P In Animals _
Where P(1) = "ant" Select String.Join(" "c, P)
MsgBox(String.Join(NewLine, AntsOnSecond.ToArray), , _
"'ant' an zweiter Stelle")
Case sender Is btPriceOfAll
Using TP = New Microsoft.VisualBasic.FileIO.TextFieldParser( _
"..\..\Article.csv")
With TP
.HasFieldsEnclosedInQuotes = True
.TextFieldType = FileIO.FieldType.Delimited
.Delimiters = New String() {";"}
.ReadLine() End With
Dim Val = Article.GetRecords(TP).Sum( _
Function(A) A.UnitPrice * A.UnitsInStock)
MsgBox(String.Format("Der gesamte Warenbestand hat einen " & _
"Verkaufswert von {0:c}", Val))
End Using
End Select
End Sub
End Class
Public Class Permutations
Public Shared Function [Of](Of T)( _
ByVal ParamArray InitArray As T()) As IEnumerable(Of T())
Return From Indices In New IndexPermutations(InitArray.Length) _
Select ApplyIndicees(InitArray, Indices)
End Function
Private Shared Function ApplyIndicees(Of T)( _
ByVal Arr As T(), ByVal Indices As Integer()) As T()
Dim RetVal(Arr.Length - 1) As T
For I = 0 To Arr.Length - 1
RetVal(I) = Arr(Indices(I))
Next
Return RetVal
End Function
End Class
Public Class IndexPermutations : Inherits Enumerable(Of Integer())
Private _Ubound As Integer
Public Sub New(ByVal Length As Integer)
_Ubound = Length - 1
End Sub
Protected Overrides Function TryMovenext( _
ByRef Current() As Integer) As Boolean
If Current Is Nothing Then
ReDim Current(_Ubound)
For I = 0 To _Ubound
Current(I) = I
Next
Return True
End If
Dim Left As Integer, Right As Integer
For Left = _Ubound - 1 To 0 Step -1
If Current(Left) < Current(Left + 1) Then Exit For
Next
If Left < 0 Then
Current = Nothing
Return False
End If
Dim LeftVal As Integer = Current(Left)
For Right = _Ubound To 0 Step -1
If Current(Right) > LeftVal Then Exit For
Next
Current(Left) = Current(Right)
Current(Right) = LeftVal
Array.Reverse(Current, Left + 1, _Ubound - Left)
Return True
End Function
End Class |