静的拡張メソッドで列挙型を受け入れ、列挙型のコンテンツにファンクターを適用しながら、そのコンテンツを反復処理する必要がある流暢なビルダー パターンを実装しています。のように (実際のコードではなく、単なる図です):
public static IValidator<IEnumerable<T>> Each<T>(
this IValidator<IEnumerable<T>> enumerable,
Func<T, bool> action)
{
foreach (T value in enumerable)
action(value);
return validator;
}
これは、列挙型ではうまく機能しますが、継承された型/インターフェイスでは失敗します。まあ言ってみれば:
IValidator<IEnumerable<Guid>> validator = ...;
IEnumerable<Guid> guids = ...;
validator.Each(guids, guid => guid != Guid.Empty); // ok
IList<Guid> guids = ...;
validator.Each(guids, guid => guid != Guid.Empty); // doesn't compile (see below)
例外は次のとおりです。
IValidator<IList<Guid>>
'Each' の定義が含まれておらず、タイプの最初の引数を受け入れる拡張メソッド 'Each'IValidator<IList<Guid>>
が見つかりませんでした (using ディレクティブまたはアセンブリ参照がありませんか?
私の質問はIValidator<T>
、より具体的には、そのジェネリック型引数の継承チェーンについてT
です。IValidator<IEnumerable<T>>
から型を代入できないのはなぜIValidator<IList<T>>
ですか? IList<T>
on ではないIEnumerable<T>
(同じ が与えられた場合)と私が考えることができる状況はありませんT
。
ジェネリック引数を に制限することT : IEnumerable<R>
はできますが、それには 2 つの型引数 (T
およびR
) が必要であり、可能であれば避けたいと思います。
何かご意見は?より良い解決策はありますか? ありがとう。