Reputation: 14971
I'm trying to create an extension method called RemoveWhere that removes an item from a List collection based on a predicate. For example
var result = products.RemoveWhere(p => p.ID == 5);
I'm using Microsoft's Where extension method signature as a starting point. Here's what I have so far:
public static List<T> RemoveWhere<T>(this List<T> source, Func<T, List<T>> predicate)
{
if (source == null)
{
throw new ArgumentNullException("source", "The sequence is null and contains no elements.");
}
if (predicate == null)
{
throw new ArgumentNullException("predicate", "The predicate function is null and cannot be executed.");
}
// how to use predicate here???
}
I don't know how to use the predicate. Can someone help me finish this? Thank you!
Upvotes: 2
Views: 3898
Reputation: 103742
The Predicate parameter should be: Func<T,bool>
public static List<T> RemoveWhere<T>(this List<T> source, Func<T, bool > predicate)
{
if (source == null)
{
throw new ArgumentNullException("source", "The sequence is null and contains no elements.");
}
if (predicate == null)
{
throw new ArgumentNullException("predicate", "The predicate function is null and cannot be executed.");
}
// how to use predicate here???
var result = new List<T>();
foreach(var item in source)
{
if(!predicate(item))
{
result.Add(item);
}
}
return result;
}
EDIT: As others have pointed out, this method is either misnamed, or it already exists on List. My guess is just that you're trying to understand how a passed in delegate is used by the method itself. For that you can look at my sample. If that is not your intent, I'll delete this answer as the code really is kind of pointless.
Upvotes: 8
Reputation: 96702
As boca observed, List<T>
already has a method to do this. A somewhat larger issue, though, is that this really isn't a scenario where you should be creating a new extension method. There's already an extension method that takes a predicate: Where
.
Granted, doing this:
var result = list.Where(x => x != 5).ToList();
is a little more code than using RemoveAll
:
list.RemoveAll(x => x == 5);
But:
list
can actually be any IEnumerable<T>
, not just a List<T>
, Where
method is a commonly used, well-documented extension method that any reasonably-skilled C# programmer can be expected to recognize on sight ToList()
and enumerate over result
.It's really hard for me to envision circumstances where I'd want to write an extension method for IEnumerable<T>
that takes a predicate. You're saving very little by making it possible for you to not use Where()
.
Upvotes: 0
Reputation: 3678
As others have pointed out, List<T>.RemoveAll
will do what you want. If however, this is a learning experience or you want to operate on any IList<T>
(which doesn't have RemoveAll
) this should do the same as RemoveAll
but as an extension method.
public static void RemoveWhere<T>(this IList<T> source, Func<T, bool> predicate)
{
//exceptions here...
// how to use predicate here???
for(int c = source.Count-1 ; c >= 0 ; c--)
{
if(predicate(source[c]))
{
source.RemoveAt(c);
}
}
}
Upvotes: 2
Reputation: 2352
There is already a method in list that does that try. Predicate should be a Predicate then you can use source.RemoveAll(predicate)
Upvotes: 6