6

我有以下扩展方法,它们编译成功并按设计运行。

public static IEnumerable<T> WhereNotEmpty<T>(this IEnumerable<T> source) where T : struct {
    return source.Where(item => !item.Equals(default(T)));
}

public static IEnumerable<V> SelectNotEmpty<T, V>(this IEnumerable<T> source, Func<T, V> selector) where V : struct {
    return source.Select(selector).WhereNotEmpty();
}

但是,为了避免装箱,我添加了一个新的通用约束,如下所示:

public static IEnumerable<T> WhereNotEmpty<T>(this IEnumerable<T> source) where T : struct, IEquatable<T> {
    return source.Where(item => !item.Equals(default(T)));
}

public static IEnumerable<V> SelectNotEmpty<T, V>(this IEnumerable<T> source, Func<T, V> selector) where V : struct, IEquatable<T> {
    return source.Select(selector).WhereNotEmpty(); // compile error!
}

我现在在SelectNotEmpty调用时遇到编译错误WhereNotEmpty

类型“V”不能用作泛型类型或方法“MyExtensions.WhereNotEmpty(System.Collections.Generic.IEnumerable)”中的类型参数“T”。没有从“V”到“System.IEquatable”的装箱转换或类型参数转换。

我确定我犯了一个愚蠢的错误,但我看不到它。有人可以为我指出吗?

4

2 回答 2

6

您对 V 的约束应该是

where V : struct, IEquatable<V>

WhereNotEmpty 中的类型T应该是IEquatable<T>,并且您在应用转换后将IEnumerable<V>传入WhereNotEmptyfrom SelectNotEmpty

public static IEnumerable<V> SelectNotEmpty<T, V>(this IEnumerable<T> source, Func<T, V> selector) where V : struct, IEquatable<V>
{
    return source.Select(selector).WhereNotEmpty();
}
于 2013-03-28T14:05:03.263 回答
1

尝试改变:

public static IEnumerable<V> SelectNotEmpty<T, V>(this IEnumerable<T> source, Func<T, V> selector) where V : struct, IEquatable<T> {
    return source.Select(selector).WhereNotEmpty(); 
}

    public static IEnumerable<V> SelectNotEmpty<T, V>(this IEnumerable<T> source, Func<T, V> selector) where V : struct, IEquatable<V> {
    return source.Select(selector).WhereNotEmpty(); 
}
于 2013-03-28T14:06:10.187 回答