[VB 2008] Erweiterungsmethode mit Einschränkungen

20/08/2010 - 14:12 von Armin Zingler | Report spam
Hi,

ich benötige eine Funktion, der man eine Liste von Listen übergeben
kann. Die Funktion soll alle Items aus allen Listen sammeln und
in einer neuen Liste zurückgeben. Habe mir folgende Methode geschrieben:

<ExtensionAttribute()> _
Friend Function Collect1(Of TItem) _
(ByVal Lists As IEnumerable(Of IEnumerable(Of TItem))) As List(Of TItem)

Dim Result As New List(Of TItem)

For Each List In Lists
Result.AddRange(List)
Next

Return Result

End Function

So weit, so gut. Nur entsteht dabei wieder dasselbe Problem, das ich
neulich erst hatte: Ein

IEnumerable(Of List(Of Integer))

làsst sich _nicht_ übergeben:

"Option Strict On" làsst keine impliziten Konvertierungen von
System.Collections.Generic.IEnumerable(Of System.Collections.Generic.List(Of Integer))
in
System.Collections.Generic.IEnumerable(Of System.Collections.Generic.IEnumerable(Of Integer)) zu.


Ich akzeptiere ja, dass das nicht geht. Abhilfe wollte ich durch folgende
Funktion schaffen:

<ExtensionAttribute()> _
Friend Function Collect2(Of TItem, TList As IEnumerable(Of TItem)) _
(ByVal Lists As IEnumerable(Of TList)) As List(Of TItem)

Hier scheitert es aber schon bei der Kompilierung:

Die Erweiterungsmethode "Collect2" verfügt über Typeinschrànkungen, die nie erfüllt werden.

Gleicher Fehler bei dieser Version:

<ExtensionAttribute()> _
Friend Function Collect3( _
Of TItem, _
TListInner As IEnumerable(Of TItem), _
TListOuter As IEnumerable(Of TListInner)) _
(ByVal Lists As TListOuter) As List(Of TItem)


Da stellt sich mir die Frage, wie ich denn sonst eine allgemeine Methode
für den Zweck schreiben könnte. Natürlich typsicher, ohne 'as object' und
Typprüfungen oder Casts zur Laufzeit. Das muss doch möglich sein! Mir
fehlt nur gerade die Idee. Bin schon ganz deprimiert weil ich das nicht
hinbekomme. :-( ;)

Armin
 

Lesen sie die antworten

#1 Peter Fleischer
21/08/2010 - 07:18 | Warnen spam
Dies ist eine mehrteilige Nachricht im MIME-Format.

=_NextPart_000_023B_01CB4101.0203D750
format=flowed;
reply-type=original

"Armin Zingler" schrieb im Newsbeitrag
news:
...
So weit, so gut. Nur entsteht dabei wieder dasselbe Problem, das ich
neulich erst hatte: Ein

IEnumerable(Of List(Of Integer))

làsst sich _nicht_ übergeben:

"Option Strict On" làsst keine impliziten Konvertierungen von
System.Collections.Generic.IEnumerable(Of
System.Collections.Generic.List(Of Integer))
in
System.Collections.Generic.IEnumerable(Of
System.Collections.Generic.IEnumerable(Of Integer)) zu.



Hi Armin,
nachfolgend eine Demo, wie das problemlos geht:

Public Class Form1

Private dgv As New DataGridView With {.Dock = DockStyle.Fill}

Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
'
Me.Controls.AddRange(New Control() {dgv})
'
Dim l1 As New List(Of Cx2)
For i = 1 To 9
l1.Add(New Cx2(i))
Next
Dim res1 = From e1 In l1
'
Dim c As New Cx1
Dim l2 = c.Collect1(Of Cx4)(l1)
'
dgv.DataSource = l2

End Sub

End Class

Friend Class Cx1

Friend Function Collect1(Of TItem) _
(ByVal Lists As IEnumerable(Of IEnumerable(Of TItem))) As List(Of
TItem)

Dim Result As New List(Of TItem)

For Each List In Lists
Result.AddRange(List)
Next

Return Result

End Function
End Class

Friend Class Cx2
Implements IEnumerable(Of Cx4)

Private l As New List(Of Cx4)

Public Sub New(ByVal n As Integer)
Dim rnd As New Random
For i = 1 To 10
l.Add(New Cx4 With {.Name = String.Format("{0:0000} Zeile {1}
{2:0000}", rnd.Next(1, 100), n, i)})
Next
End Sub

Public Function GetEnumerator() As
System.Collections.Generic.IEnumerator(Of Cx4) Implements
System.Collections.Generic.IEnumerable(Of Cx4).GetEnumerator
Return New Cx3(l)
End Function

Public Function GetEnumerator1() As System.Collections.IEnumerator
Implements System.Collections.IEnumerable.GetEnumerator
Return New Cx3(l)
End Function

Friend Class Cx3
Implements IEnumerator(Of Cx4)

Private l As List(Of Cx4)
Private i As Integer = -1

Public Sub New(ByVal l As List(Of Cx4))
Me.l = l
End Sub

Public ReadOnly Property Current As Cx4 Implements
System.Collections.Generic.IEnumerator(Of Cx4).Current
Get
If i < 0 Then Return Nothing Else Return l(i)
End Get
End Property

Public ReadOnly Property Current1 As Object Implements
System.Collections.IEnumerator.Current
Get
If i < 0 Then Return Nothing Else Return l(i)
End Get
End Property

Public Function MoveNext() As Boolean Implements
System.Collections.IEnumerator.MoveNext
i += 1
Return i < l.Count
End Function

Public Sub Reset() Implements System.Collections.IEnumerator.Reset
i = -1
End Sub

#Region "IDisposable Support"
Private disposedValue As Boolean ' To detect redundant calls

' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: dispose managed state (managed objects).
End If

' TODO: free unmanaged resources (unmanaged objects) and override
Finalize() below.
' TODO: set large fields to null.
End If
Me.disposedValue = True
End Sub

' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean)
above has code to free unmanaged resources.
'Protected Overrides Sub Finalize()
' ' Do not change this code. Put cleanup code in Dispose(ByVal
disposing As Boolean) above.
' Dispose(False)
' MyBase.Finalize()
'End Sub

' This code added by Visual Basic to correctly implement the disposable
pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal
disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region

End Class

End Class

Friend Class Cx4
Public Property Name As String
End Class

Viele Gruesse
Peter


=_NextPart_000_023B_01CB4101.0203D750
name="x.htm"
filename="x.htm"

<p></p><pre lang="x-vbnet">Public <span
style="color:#0000FF;">Class</span> <span
style="color:#2B91AF;">Form1</span>

<span style="color:#0000FF;">Private</span> dgv <span
style="color:#0000FF;">As</span> <span style="color:#0000FF;">New</span>
<span style="color:#2B91AF;">DataGridView</span> <span
style="color:#0000FF;">With</span> {.Dock = <span
style="color:#2B91AF;">DockStyle</span>.Fill}

<span style="color:#0000FF;">Private</span> <span
style="color:#0000FF;">Sub</span> Form1_Load(<span
style="color:#0000FF;">ByVal</span> sender <span
style="color:#0000FF;">As</span> System.<span
style="color:#2B91AF;">Object</span>, _
<span style="color:#0000FF;">ByVal</span> e <span
style="color:#0000FF;">As</span> System.<span
style="color:#2B91AF;">EventArgs</span>) <span
style="color:#0000FF;">Handles</span> <span
style="color:#0000FF;">MyBase</span>.Load
<span style="color:#008000;">&#39;</span>
<span style="color:#0000FF;">Me</span>.Controls.AddRange(<span
style="color:#0000FF;">New</span> <span
style="color:#2B91AF;">Control</span>() {dgv})
<span style="color:#008000;">&#39;</span>
<span style="color:#0000FF;">Dim</span> l1 <span
style="color:#0000FF;">As</span> <span style="color:#0000FF;">New</span>
<span style="color:#2B91AF;">List</span>(<span
style="color:#0000FF;">Of</span> <span style="color:#2B91AF;">Cx2</span>)
<span style="color:#0000FF;">For</span> i = 1 <span
style="color:#0000FF;">To</span> 9
l1.Add(<span style="color:#0000FF;">New</span> <span
style="color:#2B91AF;">Cx2</span>(i))
<span style="color:#0000FF;">Next</span>
<span style="color:#0000FF;">Dim</span> res1 = <span
style="color:#0000FF;">From</span> e1 <span style="color:#0000FF;">In</span>
l1
<span style="color:#008000;">&#39;</span>
<span style="color:#0000FF;">Dim</span> c <span
style="color:#0000FF;">As</span> <span style="color:#0000FF;">New</span>
<span style="color:#2B91AF;">Cx1</span>
<span style="color:#0000FF;">Dim</span> l2 = c.Collect1(<span
style="color:#0000FF;">Of</span> <span
style="color:#2B91AF;">Cx4</span>)(l1)
<span style="color:#008000;">&#39;</span>
<span style="color:#000000;"> dgv.DataSource = l2</span>

<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">Sub</span>

<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">Class</span>

<span style="color:#0000FF;">Friend</span> <span
style="color:#0000FF;">Class</span> <span style="color:#2B91AF;">Cx1</span>

<span style="color:#0000FF;">Friend</span> <span
style="color:#0000FF;">Function</span> Collect1(<span
style="color:#0000FF;">Of</span> TItem) _
(<span style="color:#0000FF;">ByVal</span> Lists <span
style="color:#0000FF;">As</span> <span
style="color:#2B91AF;">IEnumerable</span>(<span
style="color:#0000FF;">Of</span> <span
style="color:#2B91AF;">IEnumerable</span>(<span
style="color:#0000FF;">Of</span> <span
style="color:#2B91AF;">TItem</span>))) <span
style="color:#0000FF;">As</span> <span
style="color:#2B91AF;">List</span>(<span style="color:#0000FF;">Of</span>
<span style="color:#2B91AF;">TItem</span>)

<span style="color:#0000FF;">Dim</span> Result <span
style="color:#0000FF;">As</span> <span style="color:#0000FF;">New</span>
<span style="color:#2B91AF;">List</span>(<span
style="color:#0000FF;">Of</span> <span style="color:#2B91AF;">TItem</span>)

<span style="color:#0000FF;">For</span> <span
style="color:#0000FF;">Each</span> List <span
style="color:#0000FF;">In</span> Lists
<span style="color:#000000;"> Result.AddRange(List)</span>
<span style="color:#0000FF;">Next</span>

<span style="color:#0000FF;">Return</span> Result

<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">Function</span>
<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">Class</span>

<span style="color:#0000FF;">Friend</span> <span
style="color:#0000FF;">Class</span> <span style="color:#2B91AF;">Cx2</span>
<span style="color:#0000FF;">Implements</span> <span
style="color:#2B91AF;">IEnumerable</span>(<span
style="color:#0000FF;">Of</span> <span style="color:#2B91AF;">Cx4</span>)

<span style="color:#0000FF;">Private</span> l <span
style="color:#0000FF;">As</span> <span style="color:#0000FF;">New</span>
<span style="color:#2B91AF;">List</span>(<span
style="color:#0000FF;">Of</span> <span style="color:#2B91AF;">Cx4</span>)

<span style="color:#0000FF;">Public</span> <span
style="color:#0000FF;">Sub</span> <span
style="color:#0000FF;">New</span>(<span style="color:#0000FF;">ByVal</span>
n <span style="color:#0000FF;">As</span> <span
style="color:#0000FF;">Integer</span>)
<span style="color:#0000FF;">Dim</span> rnd <span
style="color:#0000FF;">As</span> <span style="color:#0000FF;">New</span>
<span style="color:#2B91AF;">Random</span>
<span style="color:#0000FF;">For</span> i = 1 <span
style="color:#0000FF;">To</span> 10
l.Add(<span style="color:#0000FF;">New</span> <span
style="color:#2B91AF;">Cx4</span> <span style="color:#0000FF;">With</span>
{.Name = <span style="color:#0000FF;">String</span>.Format(<span
style="color:#A31515;">&quot;{0:0000} Zeile {1} {2:0000}&quot;</span>,
rnd.Next(1, 100), n, i)})
<span style="color:#0000FF;">Next</span>
<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">Sub</span>

<span style="color:#0000FF;">Public</span> <span
style="color:#0000FF;">Function</span> GetEnumerator() <span
style="color:#0000FF;">As</span> System.Collections.Generic.<span
style="color:#2B91AF;">IEnumerator</span>(<span
style="color:#0000FF;">Of</span> <span style="color:#2B91AF;">Cx4</span>)
<span style="color:#0000FF;">Implements</span>
System.Collections.Generic.<span
style="color:#2B91AF;">IEnumerable</span>(<span
style="color:#0000FF;">Of</span> <span
style="color:#2B91AF;">Cx4</span>).GetEnumerator
<span style="color:#0000FF;">Return</span> <span
style="color:#0000FF;">New</span> <span style="color:#2B91AF;">Cx3</span>(l)
<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">Function</span>

<span style="color:#0000FF;">Public</span> <span
style="color:#0000FF;">Function</span> GetEnumerator1() <span
style="color:#0000FF;">As</span> System.Collections.<span
style="color:#2B91AF;">IEnumerator</span> <span
style="color:#0000FF;">Implements</span> System.Collections.<span
style="color:#2B91AF;">IEnumerable</span>.GetEnumerator
<span style="color:#0000FF;">Return</span> <span
style="color:#0000FF;">New</span> <span style="color:#2B91AF;">Cx3</span>(l)
<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">Function</span>

<span style="color:#0000FF;">Friend</span> <span
style="color:#0000FF;">Class</span> <span style="color:#2B91AF;">Cx3</span>
<span style="color:#0000FF;">Implements</span> <span
style="color:#2B91AF;">IEnumerator</span>(<span
style="color:#0000FF;">Of</span> <span style="color:#2B91AF;">Cx4</span>)

<span style="color:#0000FF;">Private</span> l <span
style="color:#0000FF;">As</span> <span
style="color:#2B91AF;">List</span>(<span style="color:#0000FF;">Of</span>
<span style="color:#2B91AF;">Cx4</span>)
<span style="color:#0000FF;">Private</span> i <span
style="color:#0000FF;">As</span> <span style="color:#0000FF;">Integer</span>
= -1

<span style="color:#0000FF;">Public</span> <span
style="color:#0000FF;">Sub</span> <span
style="color:#0000FF;">New</span>(<span style="color:#0000FF;">ByVal</span>
l <span style="color:#0000FF;">As</span> <span
style="color:#2B91AF;">List</span>(<span style="color:#0000FF;">Of</span>
<span style="color:#2B91AF;">Cx4</span>))
<span style="color:#0000FF;">Me</span>.l = l
<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">Sub</span>

<span style="color:#0000FF;">Public</span> <span
style="color:#0000FF;">ReadOnly</span> <span
style="color:#0000FF;">Property</span> Current <span
style="color:#0000FF;">As</span> <span style="color:#2B91AF;">Cx4</span>
<span style="color:#0000FF;">Implements</span>
System.Collections.Generic.<span
style="color:#2B91AF;">IEnumerator</span>(<span
style="color:#0000FF;">Of</span> <span
style="color:#2B91AF;">Cx4</span>).Current
<span style="color:#0000FF;">Get</span>
<span style="color:#0000FF;">If</span> i &lt; 0 <span
style="color:#0000FF;">Then</span> <span
style="color:#0000FF;">Return</span> <span
style="color:#0000FF;">Nothing</span> <span
style="color:#0000FF;">Else</span> <span
style="color:#0000FF;">Return</span> l(i)
<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">Get</span>
<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">Property</span>

<span style="color:#0000FF;">Public</span> <span
style="color:#0000FF;">ReadOnly</span> <span
style="color:#0000FF;">Property</span> Current1 <span
style="color:#0000FF;">As</span> <span style="color:#0000FF;">Object</span>
<span style="color:#0000FF;">Implements</span> System.Collections.<span
style="color:#2B91AF;">IEnumerator</span>.Current
<span style="color:#0000FF;">Get</span>
<span style="color:#0000FF;">If</span> i &lt; 0 <span
style="color:#0000FF;">Then</span> <span
style="color:#0000FF;">Return</span> <span
style="color:#0000FF;">Nothing</span> <span
style="color:#0000FF;">Else</span> <span
style="color:#0000FF;">Return</span> l(i)
<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">Get</span>
<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">Property</span>

<span style="color:#0000FF;">Public</span> <span
style="color:#0000FF;">Function</span> MoveNext() <span
style="color:#0000FF;">As</span> <span style="color:#0000FF;">Boolean</span>
<span style="color:#0000FF;">Implements</span> System.Collections.<span
style="color:#2B91AF;">IEnumerator</span>.MoveNext
<span style="color:#000000;"> i += 1</span>
<span style="color:#0000FF;">Return</span> i &lt; l.Count
<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">Function</span>

<span style="color:#0000FF;">Public</span> <span
style="color:#0000FF;">Sub</span> Reset() <span
style="color:#0000FF;">Implements</span> System.Collections.<span
style="color:#2B91AF;">IEnumerator</span>.Reset
<span style="color:#000000;"> i = -1</span>
<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">Sub</span>

<span style="color:#0000FF;">#Region</span> <span
style="color:#A31515;">&quot;IDisposable Support&quot;</span>
<span style="color:#0000FF;">Private</span> disposedValue <span
style="color:#0000FF;">As</span> <span style="color:#0000FF;">Boolean</span>
<span style="color:#008000;">&#39; To detect redundant calls</span>

<span style="color:#008000;">&#39; IDisposable</span>
<span style="color:#0000FF;">Protected</span> <span
style="color:#0000FF;">Overridable</span> <span
style="color:#0000FF;">Sub</span> Dispose(<span
style="color:#0000FF;">ByVal</span> disposing <span
style="color:#0000FF;">As</span> <span
style="color:#0000FF;">Boolean</span>)
<span style="color:#0000FF;">If</span> <span
style="color:#0000FF;">Not</span> <span
style="color:#0000FF;">Me</span>.disposedValue <span
style="color:#0000FF;">Then</span>
<span style="color:#0000FF;">If</span> disposing <span
style="color:#0000FF;">Then</span>
<span style="color:#008000;">&#39; TODO: dispose managed state
(managed objects).</span>
<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">If</span>

<span style="color:#008000;">&#39; TODO: free unmanaged resources
(unmanaged objects) and override Finalize() below.</span>
<span style="color:#008000;">&#39; TODO: set large fields to
null.</span>
<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">If</span>
<span style="color:#0000FF;">Me</span>.disposedValue = <span
style="color:#0000FF;">True</span>
<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">Sub</span>

<span style="color:#008000;">&#39; TODO: override Finalize() only if
Dispose(ByVal disposing As Boolean) above has code to free unmanaged
resources.</span>
<span style="color:#008000;">&#39;Protected Overrides Sub
Finalize()</span>
<span style="color:#008000;">&#39; &#39; Do not change this code.
Put cleanup code in Dispose(ByVal disposing As Boolean) above.</span>
<span style="color:#008000;">&#39; Dispose(False)</span>
<span style="color:#008000;">&#39; MyBase.Finalize()</span>
<span style="color:#008000;">&#39;End Sub</span>

<span style="color:#008000;">&#39; This code added by Visual Basic to
correctly implement the disposable pattern.</span>
<span style="color:#0000FF;">Public</span> <span
style="color:#0000FF;">Sub</span> Dispose() <span
style="color:#0000FF;">Implements</span> <span
style="color:#2B91AF;">IDisposable</span>.Dispose
<span style="color:#008000;">&#39; Do not change this code. Put
cleanup code in Dispose(ByVal disposing As Boolean) above.</span>
Dispose(<span style="color:#0000FF;">True</span>)
<span style="color:#2B91AF;">GC</span>.SuppressFinalize(<span
style="color:#0000FF;">Me</span>)
<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">Sub</span>
<span style="color:#0000FF;">#End</span> <span
style="color:#0000FF;">Region</span>

<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">Class</span>

<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">Class</span>

<span style="color:#0000FF;">Friend</span> <span
style="color:#0000FF;">Class</span> <span style="color:#2B91AF;">Cx4</span>
<span style="color:#0000FF;">Public</span> <span
style="color:#0000FF;">Property</span> Name <span
style="color:#0000FF;">As</span> <span style="color:#0000FF;">String</span>
<span style="color:#0000FF;">End</span> <span
style="color:#0000FF;">Class</span>
</pre><p></p><p></p><p>-- <br/>Viele Gruesse<br/><a
href="http://www.informtools.de">...</p>

=_NextPart_000_023B_01CB4101.0203D750--

Ähnliche fragen