See below the C# for the VB.Net version - note that there's one additional class (FooFinder) since there are no anonymous methods in VB.NET, so I needed something to be able to store the match state.
Here's a more "functional" way to accomplish the same thing, but still using C# 2.0 syntax. Note the important difference from other solutions (looping/dictionaries) is the use of the FindAll method on List, which will iterate over your collection and return all items for which the delegate returns true.
C#:
using System;
using System.Collections.Generic;
namespace SplitList
{
class Program
{
class Foo
{
public Foo(string propertyA, int number)
{
_propertyA = propertyA;
_number = number;
}
private int _number;
private string _propertyA;
public string PropertyA
{
get { return _propertyA; }
}
public int Number
{
get { return _number; }
}
}
static void Main(string[] args)
{
List<Foo> foos = new List<Foo>();
foos.Add(new Foo("ValueA", 1));
foos.Add(new Foo("ValueA", 2));
foos.Add(new Foo("ValueA", 3));
foos.Add(new Foo("ValueA", 4));
foos.Add(new Foo("ValueB", 5));
foos.Add(new Foo("ValueB", 6));
foos.Add(new Foo("ValueC", 7));
foos.Add(new Foo("ValueC", 8));
foos.Add(new Foo("ValueC", 9));
List<Foo> aFoos = foos.FindAll(delegate(Foo f) { return f.PropertyA == "ValueA"; });
List<Foo> bFoos = foos.FindAll(delegate(Foo f) { return f.PropertyA == "ValueB"; });
List<Foo> cFoos = foos.FindAll(delegate(Foo f) { return f.PropertyA == "ValueC"; });
WriteFoos("ValueA", aFoos);
WriteFoos("ValueB", bFoos);
WriteFoos("ValueC", cFoos);
Console.ReadLine();
}
private static void WriteFoos(string propertyAValue, List<Foo> list)
{
Console.WriteLine("Group {0}:", propertyAValue);
list.ForEach(delegate(Foo f)
{
Console.WriteLine("Number:{0}, PropertyA:{1}", f.Number, f.PropertyA);
});
}
}
}
VB.NET:
Module Module1
Class FooFinder
Public Sub New(ByVal propertyAValue As String)
Me.PropertyAValue = propertyAValue
End Sub
Public ReadOnly PropertyAValue As String
Function Matches(ByVal f As Foo) As Boolean
Return (f.PropertyAValue = Me.PropertyAValue)
End Function
End Class
Class Foo
Public Sub New(ByVal propertyAValue As String, ByVal number As Integer)
_propertyAValue = propertyAValue
_number = number
End Sub
Private _propertyAValue As String
Private _number As Integer
Public Property PropertyAValue() As String
Get
Return _propertyAValue
End Get
Set(ByVal value As String)
_propertyAValue = value
End Set
End Property
Public Property Number() As Integer
Get
Return _number
End Get
Set(ByVal value As Integer)
_number = value
End Set
End Property
End Class
Sub Main()
Dim foos As New List(Of Foo)
foos.Add(New Foo("ValueA", 1))
foos.Add(New Foo("ValueA", 2))
foos.Add(New Foo("ValueA", 3))
foos.Add(New Foo("ValueB", 4))
foos.Add(New Foo("ValueB", 5))
foos.Add(New Foo("ValueC", 6))
foos.Add(New Foo("ValueC", 7))
foos.Add(New Foo("ValueC", 8))
foos.Add(New Foo("ValueC", 9))
Dim aFoos As List(Of Foo) = foos.FindAll(AddressOf New FooFinder("ValueA").Matches)
Dim bFoos As List(Of Foo) = foos.FindAll(AddressOf New FooFinder("ValueB").Matches)
Dim cFoos As List(Of Foo) = foos.FindAll(AddressOf New FooFinder("ValueC").Matches)
WriteFoos("ValueA", aFoos)
WriteFoos("ValueB", bFoos)
WriteFoos("ValueC", cFoos)
Console.ReadLine()
End Sub
Private Sub WriteFoos(ByVal propertyAValue As String, ByVal list As List(Of Foo))
Console.WriteLine("PropertyAValue:{0}", propertyAValue)
For Each f As Foo In list
Console.WriteLine("Number:{0}, PropertyAValue:{1}", f.Number, f.PropertyAValue)
Next
End Sub
End Module