Tuesday, January 24, 2006
Filtering Generic Lists
I have to say that the more i work with Generics, the more i think they're the best thing to be added to C# 2.0. Recently I had a List<> of Groups and wanted to discover whether a certain User existed in any of those groups. There are a number of ways to do this, but traditionally you may iterate over the groups using foreach and then iterate acorss the members, check whether any UserID of a member matched the UserID of the User entity that was passed and store any matches. You may write a custom collection and add a method to do this for you, but all in all, performing searching on objects was a bit of a pain.
Generics makes this a whole lot easer. Using Predicates and delagates which can be used to perform custom searches on your generic collections and work without writing custom classes of iterations and so on.
So, back to my problem. Let's first wite a GroupFilter class that will be used in the Predicate for our filtering. You pass the ID of the user you are searching for in the constuctor of this class. I then define a method that is delegated to by this Predicate to evaluate whether our test condition is true. As you call a method such as Exists() on a generic collection, with this class as the Predicate, each item in the List is passed in context to the delegated method. In my case i have a List and so each User in the list will be passed to this method.
public class GroupFilter
{
int _userid;
public GroupFilter(int userid)
{
_userid = userid;
}
public bool HasUser(User user)
{
return user.UserID == _userid;
}
}
There are a number of ways we can proivde access to this from a software client perspective, but i prefer to wrap these into common queries and provide a simple interface to it and in my case i just define a ContainsUser() method which takes the id of the user to search for. A Predicate is then defined and an instance of the GroupFilter class is constructed using the id of the user we are going to search for. Finally the delegate is set to a new instance of the Predicate which points to the HasUser method, saying that when this Predicate is used, the HasSer method will be delegates to provide the result. The Predicate can then be used with a bunch of methods,but in my case i just want to test whether the user exists in the Members collection of the Group and so i pass it to the Exists() method, which returns true if the user exists in the group.
public bool ContainsUser(int memberid)
{
//create an instance of the hasuser predicate
Predicate hasUser;
//now instantiate a group filter for members
GroupFilter filter = new GroupFilter(memberid);
//set up the delagate for the list filter
hasUser = new Predicate(filter.HasUser);
return this.Members.Exists(hasUser);
}
As i said, fantastic stuff and I intend to use them quite a bit more. I hope sharing this will help as finding info that was more than string evaluation was a bit of a pain.
Generics makes this a whole lot easer. Using Predicates and delagates which can be used to perform custom searches on your generic collections and work without writing custom classes of iterations and so on.
So, back to my problem. Let's first wite a GroupFilter class that will be used in the Predicate for our filtering. You pass the ID of the user you are searching for in the constuctor of this class. I then define a method that is delegated to by this Predicate to evaluate whether our test condition is true. As you call a method such as Exists() on a generic collection, with this class as the Predicate, each item in the List is passed in context to the delegated method. In my case i have a List
public class GroupFilter
{
int _userid;
public GroupFilter(int userid)
{
_userid = userid;
}
public bool HasUser(User user)
{
return user.UserID == _userid;
}
}
There are a number of ways we can proivde access to this from a software client perspective, but i prefer to wrap these into common queries and provide a simple interface to it and in my case i just define a ContainsUser() method which takes the id of the user to search for. A Predicate is then defined and an instance of the GroupFilter class is constructed using the id of the user we are going to search for. Finally the delegate is set to a new instance of the Predicate which points to the HasUser method, saying that when this Predicate is used, the HasSer method will be delegates to provide the result. The Predicate can then be used with a bunch of methods,but in my case i just want to test whether the user exists in the Members collection of the Group and so i pass it to the Exists() method, which returns true if the user exists in the group.
public bool ContainsUser(int memberid)
{
//create an instance of the hasuser predicate
Predicate
//now instantiate a group filter for members
GroupFilter filter = new GroupFilter(memberid);
//set up the delagate for the list filter
hasUser = new Predicate
return this.Members.Exists(hasUser);
}
http://stevenR2.com
... a brief history
Site XML Feed
www.flickr.com |
Posts By Date
Profiles
- my taghop.org web
- taghop linkblogs
- todo list
- who i know
- flickr photos
- delicious links
- evdb events
- my things
- odeo subscriptions
NeighBloggers
taghop
Also made in Scotland
- Tarmac (John Loudon MacAdam)
- McIntosh Coat (Charles McIntosh)
- James Clerk Maxwell
- David Livingstone
- Television (John Logie Baird)
- BBC (Lord Reith)
- Kelvin Temperatures (William Thomson)
- RADAR (Sir Robert Alexander Watson-Watt)
- Steam Engine (James Watt)
- Americanism (John Witherspoon)
- Telephone (Alexander Graham Bell)
- Penicillin (Sir Alexander Fleming)
- Patron Saint of Ireland (Saint Patrick)
- Charles Rennie Mackintosh
- Celtic FC (Jock Stein)
- Treasure Island (Robert Louis Stevenson)
- Paddle Steamer (William Symington)
- Encylopaedia Britannica (William Smellie)
- Las Palmas Observatory (Charles Piazzi Smyth)
- The Bank of England (William Paterson)
- Logarithms & the Decimal Point (John Napier)
- The World Cup (Sir Thomas Lipton)
- MoreOver.com (David Galbraith)
- Blackboard (James Pillans)
- Liverpool FC (Bill Shankly)
- Iron Plough (James Small)
- Robinson Crusoe (Alexander Selkirk)
- Helium (Sir William Ramsay)
- Sociology (Adam Ferguson)
- Harry Potter
- Landspeed Record (Richard Noble)
- Hot Blast Oven (James Beaumont Neilson)
- Coal-Gas Lighting (William Murdock)
- Prime Minister of Canada (Sir John Alexander MacDonald)
- The Bicycle (Kirkpatrick Macmillan)
- Reflecting Telescope (James Gregory)
- The World's Worst Poet (William Topaz McGonagall)
- Geology (James Hutton)
- Carnegie Mellon (Andrew Carnegie)
- Carnegie Institution (Andrew Carnegie)
- Grandfather of the United States (Robert Dinwiddie)
- Universal Standard Time (Sir Sandford Fleming)
- Latent Heat & Carbon Dioxide (Joseph Black)
- James Bond (Sean Connery)
- Rob Stewart
- Auld Lang Syne (Robert Burns)
- Billy Connolly
- Annie Lennox
- U.S. Navy (John Paul Jones)
- Chariots of Fire (Eric Henry Liddell)
- Cure for Scurvy (James Lind)
- Tea Bags (Sir Thomas Lipton)
- Vacuum flask (Sir James Dewar)
- Postage Stamp (James Chalmers)
- Clerk Cycle Gas Engine (Sir Dugald Clerk)
- Cure for Malaria (George Cleghorn)
- Cure for Malaria (George Cleghorn)
- Groundskeeper Willie
- Peter Pan (Sir James Barrie)
- Kaleidoscope (Sir David Brewster)
- Toronto Globe (George Brown)
- Sherlock Holmes (Sir Arthur Conan Doyle)
- Graham's Law (Thomas Graham)
- The Wind in the Willows (Kenneth Grahame)
Release 2.0
Release 1.0
What I know
I Read
Archives
- July 17, 2005
- July 18, 2005
- July 19, 2005
- July 20, 2005
- July 21, 2005
- July 22, 2005
- July 27, 2005
- July 28, 2005
- August 01, 2005
- August 02, 2005
- August 03, 2005
- August 04, 2005
- August 07, 2005
- August 08, 2005
- August 09, 2005
- August 10, 2005
- August 11, 2005
- August 12, 2005
- August 13, 2005
- August 17, 2005
- August 19, 2005
- August 22, 2005
- August 24, 2005
- August 25, 2005
- August 27, 2005
- August 29, 2005
- August 30, 2005
- September 01, 2005
- September 02, 2005
- September 03, 2005
- September 04, 2005
- September 21, 2005
- September 22, 2005
- September 23, 2005
- September 30, 2005
- October 04, 2005
- October 06, 2005
- October 11, 2005
- October 14, 2005
- October 25, 2005
- October 27, 2005
- November 02, 2005
- November 08, 2005
- November 10, 2005
- November 12, 2005
- November 14, 2005
- November 16, 2005
- November 22, 2005
- December 02, 2005
- December 07, 2005
- December 23, 2005
- December 30, 2005
- January 02, 2006
- January 10, 2006
- January 11, 2006
- January 12, 2006
- January 14, 2006
- January 15, 2006
- January 16, 2006
- January 19, 2006
- January 20, 2006
- January 24, 2006
- January 25, 2006
- January 26, 2006
- January 30, 2006
- February 07, 2006
- February 08, 2006
- February 09, 2006
- February 20, 2006
- February 22, 2006
- February 23, 2006
- February 24, 2006
- February 27, 2006
- February 28, 2006
- March 01, 2006
- March 06, 2006
- March 08, 2006
- March 10, 2006
- March 13, 2006
- March 22, 2006
- March 24, 2006
- March 28, 2006
- March 29, 2006
- March 30, 2006
- March 31, 2006
- April 02, 2006
- April 06, 2006
- April 07, 2006
- April 13, 2006
- April 20, 2006
- April 26, 2006
- April 27, 2006
- April 28, 2006
- April 29, 2006
- April 30, 2006
- May 01, 2006
- May 02, 2006
- May 03, 2006
- May 04, 2006
- May 05, 2006
- May 07, 2006
- May 08, 2006
- May 10, 2006
- May 11, 2006
- May 15, 2006
- May 16, 2006
- June 02, 2006
- June 05, 2006
- June 06, 2006
- June 09, 2006
- June 11, 2006
- June 12, 2006
- June 13, 2006
- June 14, 2006
- June 20, 2006
- June 24, 2006
- June 26, 2006
- June 27, 2006
- June 29, 2006
- June 30, 2006
- July 01, 2006
- July 03, 2006
- July 08, 2006
- July 10, 2006
- July 12, 2006
- July 13, 2006
- July 25, 2006
- July 28, 2006
- August 01, 2006
- August 02, 2006
- August 05, 2006
- August 07, 2006
- August 08, 2006
- August 15, 2006
- August 22, 2006
- August 24, 2006
- August 27, 2006
- September 06, 2006
- September 07, 2006
- September 08, 2006
- September 11, 2006
- September 13, 2006
- September 14, 2006
- September 15, 2006
- September 21, 2006
- September 25, 2006
- October 02, 2006
- October 03, 2006
- October 25, 2006
- November 01, 2006
- November 10, 2006
- November 14, 2006
- November 15, 2006
- November 16, 2006
- November 17, 2006
- November 18, 2006
- November 20, 2006
- November 21, 2006
- November 29, 2006
- November 30, 2006
- December 08, 2006
- December 09, 2006