List <T>的扩展方法不接受List <int>

Mar*_*ark 1 c# generics extension-methods

我目前正在尝试扩展方法.我的目标是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>();
        }
    }
Run Code Online (Sandbox Code Playgroud)

所以这适用于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>();
}
Run Code Online (Sandbox Code Playgroud)

我是非常新的通用的东西,所以我怎么能定义我的where子句也接受List<int>呢?

马克

Jon*_*eet 9

您的扩展方法在其约束方面无效:

   public static T FindFirstAfterIndex<T>(this List<T> list, int index, T item) 
       where T : class  where T : struct
Run Code Online (Sandbox Code Playgroud)

(where T : struct约束在您的问题上一直滚动到右侧.)

您不能为此类型参数指定两个约束子句.您可以指定一个具有多个约束的约束子句(例如where T : class, IDisposable),但它不能包含classstruct约束.

如果您的扩展方法实际上只有一个约束并且该约束是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();
}
Run Code Online (Sandbox Code Playgroud)

现在它适用于任何列表,并将使用默认的相等语义T(例如,它将使其更常规地工作List<string>),并且还允许您在需要时提供自定义相等比较器.


Mik*_*sen 6

int不是一个类.int将被装入结构(Int32).

您必须删除该条款:

where T : class
Run Code Online (Sandbox Code Playgroud)

或者Int32?改为使用.

更新:

Int32? 很可能不会起作用,因为从技术上来说它仍然是一个结构:

public struct Nullable<T> where T : struct
Run Code Online (Sandbox Code Playgroud)

如果要在此处使用结构,最好的办法是删除类约束.

  • @Davy8可能是因为`int32?`不满足`where T:class`约束.另外,`int`和`Int32`在C#中也是一样的.`int`是`System.Int32`类型的别名.而且泛型实际上*避免*拳击值类型; 这是他们很棒的原因之一! (2认同)

Bro*_*ass 6

只需删除class约束:

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

}
Run Code Online (Sandbox Code Playgroud)