从'V'到'System.IEquatable <v>'</v>没有装箱转换或类型参数转换

时间:2013-03-28 13:58:02

标签: c# generics

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

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的编译错误:

  

类型&#39; V&#39;不能用作类型参数&#39; T&#39;在泛型中   或方法   &#39; MyExtensions.WhereNotEmpty(System.Collections.Generic.IEnumerable)&#39 ;.   没有拳击转换或类型参数转换来自&#39; V&#39;至   &#39; System.IEquatable&#39;

我确定我犯了一个愚蠢的错误,但我无法看到它。有人能指点一下吗?

2 个答案:

答案 0 :(得分:6)

你对V的约束应该是

where V : struct, IEquatable<V>

WhereNotEmpty中的T类型应为IEquatable<T>,并且您在应用转换后将IEnumerable<V>传递给WhereNotEmpty 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();
}

答案 1 :(得分: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(); 
}