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はあるべきであり、変換を適用した後にfromにIEquatable<T>渡しています。IEnumerable<V>WhereNotEmptySelectNotEmpty

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 に答える