Results 1 to 7 of 7

Thread: IEnumerable(Of x) - Return members that are y

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Jul 2002
    Location
    Dublin, Ireland
    Posts
    2,148

    IEnumerable(Of x) - Return members that are y

    Based on this C# code - an extension to IEnumerable(Of ?) that returns all the members of it that are of a particular type:-

    Code:
    ''' <summary>
    ''' Class to allow type-based list filtering
    ''' </summary>
    ''' <typeparam name="TSource">
    ''' The source type in our IEnumerable(Of )
    ''' </typeparam>
    ''' <remarks>
    ''' See http://stackoverflow.com/questions/2893698/partial-generic-type-inference-possible-in-c?rq=1
    ''' </remarks>
    Public Class ThatAreWrapper(Of TSource)
    
        ReadOnly sourceCollection As IEnumerable(Of TSource)
    
        Public Iterator Function Are(Of Tresult As TSource)() As IEnumerable(Of Tresult)
            For Each sourceItem In sourceCollection
                If (TypeOf (sourceItem) Is Tresult) Then
                    Yield sourceItem
                End If
            Next
        End Function
    
        Public Sub New(ByVal source As IEnumerable(Of TSource))
            sourceCollection = source
        End Sub
    
    End Class
    This is used in a module to provide an extension to IEnumerable(Of ?) :-
    Code:
    Imports System.Runtime.CompilerServices
    
    Public Module IEnumerableExtensions
    
        <Extension()>
        Public Function That(Of TSource)(ByVal source As IEnumerable(Of TSource)) As ThatAreWrapper(Of TSource)
            Return New ThatAreWrapper(Of TSource)(source)
        End Function
    
    End Module
    an example (unit test) of use:-
    Code:
        <TestMethod()>
        Public Sub ThatAreFilterTestMethod()
    
            Dim myList As List(Of Object) = New List(Of Object)
    
            myList.Add("Duncan")
            myList.Add(1000)
            myList.Add(New DateTime(1900, 2, 2))
            myList.Add("Jones")
    
            Dim myStrings = myList.AsEnumerable().That().Are(Of String).ToArray()
    
            Assert.AreEqual(myStrings(0), "Duncan")
    
        End Sub

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,274

    Re: IEnumerable(Of x) - Return members that are y

    Such a method already exists: OfType.
    Code:
        <TestMethod()>
        Public Sub ThatAreFilterTestMethod()
    
            Dim myList As List(Of Object) = New List(Of Object)
    
            myList.Add("Duncan")
            myList.Add(1000)
            myList.Add(New DateTime(1900, 2, 2))
            myList.Add("Jones")
    
            Dim myStrings = myList.OfType(Of String)().ToArray()
    
            Assert.AreEqual(myStrings(0), "Duncan")
    
        End Sub

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Jul 2002
    Location
    Dublin, Ireland
    Posts
    2,148

    Re: IEnumerable(Of x) - Return members that are y

    Indeed - but I think OfType() doesn't enforce type checking at compile time to ensure the source type could ever be a result type?

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,274

    Re: IEnumerable(Of x) - Return members that are y

    Quote Originally Posted by Merrion View Post
    Indeed - but I think OfType() doesn't enforce type checking at compile time to ensure the source type could ever be a result type?
    Here's the OfType method decompiled by ReSharper:
    csharp Code:
    1. public static IEnumerable<TResult> OfType<TResult>(this IEnumerable source)
    2.     {
    3.       if (source == null)
    4.         throw Error.ArgumentNull("source");
    5.       else
    6.         return Enumerable.OfTypeIterator<TResult>(source);
    7.     }
    8.  
    9.     private static IEnumerable<TResult> OfTypeIterator<TResult>(IEnumerable source)
    10.     {
    11.       foreach (object obj in source)
    12.       {
    13.         if (obj is TResult)
    14.           yield return (TResult) obj;
    15.       }
    16.     }
    I'm not sure how good your C# is but this line:
    Code:
    if (obj is TResult)
    does exactly what this line:
    Code:
    If (TypeOf (sourceItem) Is Tresult) Then
    does.

  5. #5

    Thread Starter
    PowerPoster
    Join Date
    Jul 2002
    Location
    Dublin, Ireland
    Posts
    2,148

    Re: IEnumerable(Of x) - Return members that are y

    Yeah - my VB conversion missed out this restriction (doh)
    Code:
    public IEnumerable<TResult> Are<TResult>() where TResult : TSource
        {
            foreach (var sourceItem in SourceCollection)
                if (sourceItem is TResult) yield return (TResult)sourceItem;
            }
        }

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,274

    Re: IEnumerable(Of x) - Return members that are y

    Quote Originally Posted by Merrion View Post
    Yeah - my VB conversion missed out this restriction (doh)
    Code:
    public IEnumerable<TResult> Are<TResult>() where TResult : TSource
        {
            foreach (var sourceItem in SourceCollection)
                if (sourceItem is TResult) yield return (TResult)sourceItem;
            }
        }
    Ah, I get it now. Mind you, once you've declared the method with that restriction, the implementation is the same as OfType so you could just call OfType internally.

  7. #7

    Thread Starter
    PowerPoster
    Join Date
    Jul 2002
    Location
    Dublin, Ireland
    Posts
    2,148

    Re: IEnumerable(Of x) - Return members that are y

    Correct - it should be:-
    Code:
        ''' <summary>
        ''' Class to allow type-based list filtering
        ''' </summary>
        ''' <typeparam name="TSource">
        ''' The source type in our IEnumerable(Of )
        ''' </typeparam>
        ''' <remarks>
        ''' See http://stackoverflow.com/questions/2893698/partial-generic-type-inference-possible-in-c?rq=1
        ''' </remarks>
        Public Class ThatAreWrapper(Of TSource)
    
            ReadOnly sourceCollection As IEnumerable(Of TSource)
    
            Public Function Are(Of Tresult As TSource)() As IEnumerable(Of Tresult)
                Return sourceCollection.OfType(Of Tresult)()
            End Function
    
            Public Sub New(ByVal source As IEnumerable(Of TSource))
                sourceCollection = source
            End Sub
    
        End Class
    Thanks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width