Интересно если его возможное для удаления всех объектов из того же вида из универсального Списка с помощью дополнительных методов. что-то вроде этого кодирует:
public static Remove<T>(this List<[any type]> list)
{
// some code to remove the objects of type T from the list
}
Я могу сделать это при помощи следующего кода:
public static Remove<T, K>(this List<K> list)
{
// some code to remove the objects of type T from the List<K>
}
но я хочу просто использовать на типе (T) без потребности указать любой тип K. путем выполнения, что пользователь может использовать этот дополнительный метод просто записью это:
List<object> list = new List<object>();
list.Add(1);
list.Add("text");
// remove all int type objects from the list
list.Remove<int>();
дополнительный метод, который я могу использовать, чтобы сделать что-то точно как вышеупомянутый код, - то, в чем я действительно нуждаюсь здесь.
с уважением
Не уверен, сработает это или нет ... но попробовать стоит (я не могу скомпилировать, чтобы перепроверить):
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);
}
}
Или, если вам нужно что-то более строгое (а не любой объект, который может быть приведение к типу), вы можете попробовать:
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);
}
}
Теоретически все должно быть в порядке. List
реализует IList
, который реализует IEnumerable
. IList предоставляет Remove ()
, а IEnumerable предоставляет метод расширения.
Имейте в виду, что это определенно может привести к неожиданным результатам в зависимости от типов в коллекции. Я согласен с Джоном Скитом ... это определенно уродливо.
Нужно ли вам указывать тип фильтра как общий?
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));
Я не рекомендую это, так как это похоже на API, который будет очень сложно понять и поддерживать.
При этом должно работать следующее:
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);
}
}
Вы пытаетесь сделать так, чтобы вывод типов работал на одном параметре типа, а другой указывался явно. Боюсь, что C# этого не позволяет.
Форма, использующая негенеративный IList
, приведенная Джастином, будет работать, потому что у нее только один параметр типа (тип элемента для удаления). Однако это довольно уродливо.
Это то, что вам действительно нужно настолько часто, что вы беспокоитесь об указании обоих аргументов типа?
Вот еще один вариант. Возврат используется только в том случае, если требуется сцепить метод.
public static List<TList> Remove<TList, TRemove>(this List<TList> list)
{
list.RemoveAll(item => item is TRemove);
return list;
}
Я бы, вероятно, сделал что-то вроде:
enumerable.Cast<object>().Where(o => !(o is T))
И пропустил тот факт, что enumerable - это список. (Приведение здесь используется, чтобы убедиться, что где работает, если у вас уже есть универсальное перечислимое значение, вы можете его пропустить)
благодаря великому ответу Джастина Нисснера мне удалось сделать это, используя следующий код:
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]);
}
в ответе Джастина Нисснера есть одна проблема. вы не можете удалить элемент перечисления в блоке foreach.
Сделайте шаг назад по списку и удалите те, которые соответствуют нежелательному типу.
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 );
}
}
}
Если вы всегда будете использовать List
, вы можете еще немного упростить ситуацию.
public static void RemoveAllOfType<T>( this List<object> list )
{
list.RemoveAll( item => item is T );
}
Счастливого кодинга!
Не уверен, что это подойдет
static class test
{
public static void RemAll<T>(this List<Object> self, T t) where T : Type
{
self.RemoveAll(x => x.GetType()==t);
}
}
Может быть вызвано как показано ниже
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));
}
Что вы действительно хотите сделать, так это иметь метод расширения, подобный этому:
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);
}
}
Обратите внимание, что вы можете использовать это только для List
, поскольку он реализует негенерический интерфейс IList. Интерфейс IList
не вытекает из негенеративного интерфейса IList.