拡張メソッドがインターフェイスで機能しない
-
01-07-2019 - |
質問
MVC ストアフロントに触発されて、私が取り組んでいる最新のプロジェクトは、IQueryable の拡張メソッドを使用して結果をフィルターすることです。
私はこのインターフェースを持っています。
IPrimaryKey
{
int ID { get; }
}
そして私はこの拡張メソッドを持っています
public static IPrimaryKey GetByID(this IQueryable<IPrimaryKey> source, int id)
{
return source(obj => obj.ID == id);
}
IPrimaryKey を実装する SimpleObj クラスがあるとします。SimpleObj の IQueryable がある場合、IPrimaryKey の IQueryable として明示的にキャストしない限り、GetByID メソッドは存在しません。これは理想的ではありません。
ここで何かが足りないでしょうか?
解決
正しく行えば機能します。cfeduke のソリューションは機能します。ただし、必ず作る必要はありません。 IPrimaryKey
インターフェイスジェネリック、実際、元の定義をまったく変更する必要はありません。
public static IPrimaryKey GetByID<T>(this IQueryable<T> source, int id) where T : IPrimaryKey
{
return source(obj => obj.ID == id);
}
他のヒント
編集: コンラッドの解決策ははるかに単純であるため、より優れています。以下の解決策は機能しますが、継承階層をたどらずにリフレクションを通じてクラスのメソッドが取得される ObjectDataSource と同様の状況でのみ必要となります。明らかに、ここではそれは起こっていません。
これは可能ですが、ObjectDataSource を操作するためのカスタム エンティティ フレームワーク ソリューションを設計したときに、同様のパターンを実装する必要がありました。
public interface IPrimaryKey<T> where T : IPrimaryKey<T>
{
int Id { get; }
}
public static class IPrimaryKeyTExtension
{
public static IPrimaryKey<T> GetById<T>(this IQueryable<T> source, int id) where T : IPrimaryKey<T>
{
return source.Where(pk => pk.Id == id).SingleOrDefault();
}
}
public class Person : IPrimaryKey<Person>
{
public int Id { get; set; }
}
使用例の抜粋:
var people = new List<Person>
{
new Person { Id = 1 },
new Person { Id = 2 },
new Person { Id = 3 }
};
var personOne = people.AsQueryable().GetById(1);
ジェネリックには継承パターンに従う機能がないため、これは機能しません。つまり。IQueryable<SimpleObj> は IQueryable<IPrimaryKey> の継承ツリーにありません
所属していません StackOverflow