Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

There is no boxing conversion or type parameter conversion from 'V' to 'System.IEquatable<V>'

Tags:

c#

generics

I have the following extension methods, which compile successfully and behave as designed.

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();
}

However, in an effort to avoid the boxing, I added a new generic constraint as follows:

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!
}

I'm now getting a compile error where SelectNotEmpty calls WhereNotEmpty:

The type 'V' cannot be used as type parameter 'T' in the generic type or method 'MyExtensions.WhereNotEmpty(System.Collections.Generic.IEnumerable)'. There is no boxing conversion or type parameter conversion from 'V' to 'System.IEquatable'.

I'm sure I've made a silly mistake, but I can't see it. Could anyone point it out for me please?

like image 919
Christian Hayter Avatar asked Mar 28 '13 13:03

Christian Hayter


2 Answers

Your constraint on V should be

where V : struct, IEquatable<V>

The type T in WhereNotEmpty should be IEquatable<T> and you are passing an IEnumerable<V> into WhereNotEmpty from SelectNotEmpty after you apply the transformation.

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();
}
like image 70
Lee Avatar answered Nov 16 '22 17:11

Lee


Try to change:

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(); 
}

on

    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(); 
}
like image 40
Killo Avatar answered Nov 16 '22 16:11

Killo