метод расширения для List <T>не принимает List <int> - PullRequest
1 голос
/ 15 ноября 2011

Я сейчас экспериментирую с методами расширения.Моя цель - метод расширения для List, который находит первый элемент, который соответствует данному элементу в коллекции, после указанного индекса.

public static class Extensions
    {
        public static T FindFirstAfterIndex<T>(this List<T> list, int index, T item) where T : class                                                                                    where T : struct
        {
            return list.Skip<T>(index).Where<T>(result => result == item).First<T>();
        }
    }

, поэтому он работает для объектов класса как T.

Я также пытался:

public static T FindFirstAfterIndex<T>(this List<T> list, int index, T item) where T : class          
                                                                             where T : struct
{
    return list.Skip<T>(index).Where<T>(result => result == item).First<T>();
}

Я очень новичок в общих вещах и T, так как я могу определить мое предложение where для принятия также List<int>?

в отношении Марка

Ответы [ 4 ]

9 голосов
/ 15 ноября 2011

Ваш метод расширения недействителен с точки зрения его ограничений:

   public static T FindFirstAfterIndex<T>(this List<T> list, int index, T item) 
       where T : class  where T : struct

(Ограничение where T : struct прокручивается полностью вправо по вашему вопросу.)

Вы не можете указать два предложения ограничения для одного и того же параметра типа, как это. Вы можете указать one условие ограничения с несколькими ограничениями (например, where T : class, IDisposable), но оно не может включать ограничения class и struct.

Если ваш метод расширения на самом деле имеет только одно ограничение, и это ограничение равно where T : class, то это объясняет, почему оно недопустимо для List<int> - поскольку int не удовлетворяет ограничению ссылочного типа .

Честно говоря, ваш метод лучше написать так:

public static T FindFirstAfterIndex<T>(this IEnumerable<T> list,
                                       int index, T item)
{
    return FindFirstAfterIndex(list, index, item, EqualityComparer<T>.Default);
}

public static T FindFirstAfterIndex<T>(this IEnumerable<T> list,
                                       int index, T item,
                                       IEqualityComparer<T> comparer)
{
    return list.Skip(index)
               .Where(result => comparer.Equals(result, item))
               .First();
}

Теперь он будет работать для любого списка и будет использовать семантику равенства по умолчанию T (что сделает его более условно работающей, например, для List<string>), а также позволит вам указать Пользовательский равенство равенства, когда вы хотите.

6 голосов
/ 15 ноября 2011

Просто отбросьте ограничение class:

public static T FindFirstAfterIndex<T>(this List<T> list, int index, T item) 
{

}
6 голосов
/ 15 ноября 2011

int - это не класс. int будет упакован в структуру (Int32).

Вы должны удалить пункт:

where T : class

Или используйте Int32?.

Обновление:

Int32?, скорее всего, не будет работать, поскольку технически это все равно будет структура:

public struct Nullable<T> where T : struct

Лучше всего снять ограничения класса, если вы хотите использовать здесь структуры.

0 голосов
/ 15 ноября 2011
public static class Extensions
{
    public static T FindFirstAfterIndex<T>(this List<T> list, int index, T item)
        where T :IComparable
    {
        return list.Skip<T>(index).Where<T>(result => result.CompareTo(item)==0).First<T>();
    }
}
...