Remove objects of any type from a <T> list in C # using extension methods?
I wonder if it is possible to remove all objects from the same type from the general list using extension methods. something like this code:
public static Remove<T>(this List<[any type]> list) { // some code to remove the objects of type T from the list } I can do this using the following code:
public static Remove<T, K>(this List<K> list) { // some code to remove the objects of type T from the List<K> } but I want to just use type (T), without having to specify any type K. If the user can use this extension method, just write this:
List<object> list = new List<object>(); list.Add(1); list.Add("text"); // remove all int type objects from the list list.Remove<int>(); the extension method that I can use to do something exactly like the code above is what I really need here.
Best wishes
Not sure if this will work or not ... but it's worth it (I cannot compile double check):
public static void Remove<T>(this IList list) { if(list != null) { var toRemove = list.OfType<T>().ToList(); foreach(var item in toRemove) list.Remove(item); } } Or, if you need something a little more strict (and not any object that can be added to a type), you can try:
public static void Remove<T>(this IList list) { if(list != null) { var toRemove = list.Where(i => typeof(i) == typeof(T)).ToList(); foreach(var item in toRemove) list.Remove(item); } } In theory, you should be kind. List<T> implements IList , which implements IEnumerable . IList provides Remove() , and IEnumerable provides an extension method.
Remember that this can lead to unexpected results depending on the types in the collection. I agree with John Skeet ... it's definitely ugly.
Do you need to specify the filter type as general?
public static IEnumerable<T> Remove<T>(this IEnumerable<T> items, Type removeThese) { return items.Where(i => !removeThese.IsInstanceOfType(i)); } // usage var newSet = mylist.Remove(typeof(int)); I do not recommend this, since it is like an API that will be very difficult to understand and maintain.
The following should work:
public static void Remove<T>(this IList list) { Type type = typeof(T); var itemsToRemove = list.Cast<object>.Where(o => o.GetType() == type).ToList(); foreach(var item in itemsToRemove) { list.Remove(item); } } What you are trying to do is use the type input operation for one type parameter, but specify the other explicitly. I am afraid that C # does not allow this.
A form using the non-generic IList specified by Justin will work because it has only one type parameter (element type to delete). It's pretty ugly though.
Is that what you really need, often enough that you worry about specifying both type arguments?
What you really want to do is an extension method:
public static void Remove<T>(this IList list) { // Cycle through everything, comparing the types. for (int index = list.Count; index >= 0; --index) { // Get the object. object item = list[index]; // If the item is null, continue. if (item == null) continue; // Remove the item if the types match. if (typeof(T) == item.GetType()) list.RemoveAt(index); } } Note that you can only use it for List<T> , since it does not implement the general IList interface. The IList<T> interface does not derive from the non-generic IList interface.
Here is another option. Returns are only used if you want to bind a method.
public static List<TList> Remove<TList, TRemove>(this List<TList> list) { list.RemoveAll(item => item is TRemove); return list; } I would probably do something like:
enumerable.Cast<object>().Where(o => !(o is T)) And skip the fact that the list is enumerated. (Cast is used here to ensure that Where works, if you already have a shared account, then you can skip it)
Take a step back through the list and delete those that correspond to the unwanted type.
public static void RemoveAllOfType<T>( this IList list ) { for( int index = list.Count - 1; index >= 0; index -- ) { if( list[index] is T ) { list.RemoveAt( index ); } } } If you always use List<object> , you can simplify things a bit more.
public static void RemoveAllOfType<T>( this List<object> list ) { list.RemoveAll( item => item is T ); } Happy coding!
Not sure what this will do
static class test { public static void RemAll<T>(this List<Object> self, T t) where T : Type { self.RemoveAll(x => x.GetType()==t); } } Can be invoked as shown below.
static void Main(string[] args) { List<object> ll = new List<object>() { 1, 2, "abcd", "xyz", 22.3, 900, "junk" }; ll.RemAll(typeof(int)); ll.ForEach(x => Console.WriteLine(x)); } thanks to Justin Nissner's friendly answer, I managed to do this using the following code:
public static void Remove<T>(this IList list) { ArrayList deleteList = new ArrayList(); foreach (var item in list) if (item.GetType() == typeof(T)) deleteList.Add(item); for (int i = 0; i < deleteList.Count; i++) list.Remove(deleteList[i]); } Justin Nissner's answer has one problem. you cannot remove the enumarator element in the foreach block.