http://projecteuler.netで、問題の解決策を実装するための独自の小さなアプリを入手しました。ProblemBase
ID、名前と説明のテキスト、ソルバー関数など、問題に関するメタ情報を含むという名前の基本クラスがあります。すべての問題の実装は、このクラスから派生します。
実装のリストは現在かなり大きくなっているので、ソリューションコンテナーを手動で保守する代わりに、私は初めてリフレクションランドに足を踏み入れました。アイデアは、アセンブリから派生するすべてのタイプを見つけ、ProblemBase
それらをアプリケーションの問題列挙(Problems
以下のコード)にインスタンス化して、GUIからそれらを操作できるようにすることです。これが私の現在の実装です:
private void FindProblemTypes()
{
var problemBaseType = typeof(ProblemBase);
var problemTypes = (from t in Assembly.GetAssembly(problemBaseType).GetTypes()
where t != problemBaseType && problemBaseType.IsAssignableFrom(t)
select t).ToList();
Problems = new ObservableCollection<ProblemBase>();
foreach (var problemType in problemTypes)
{
Problems.Add((ProblemBase)Activator.CreateInstance(problemType));
}
Problems = new ObservableCollection<ProblemBase>(Problems.OrderBy(t => t.Id));
}
動作していますが、少しクリーンアップしたいと思います。現在、私は最初に派生型のリストを作成し、次にそれらをコレクションに挿入し、次にさらに別のコレクションを作成して型をIDで並べ替えています。私がやりたいのは、最初のLINQコレクションから直接ObservableCollectionを作成することです。orderby t.Id
LINQステートメントを追加したいのですが、型コレクションにSystem.Type
オブジェクトではなくProblemBase
オブジェクトが含まれているため、そのプロパティは使用できず、LINQクエリ内で変数をベースオブジェクトに変換できません。要求している型情報がコンパイル時にわからないためだと思いProblemBase
ますが、クエリ内からオブジェクトのように扱う方法は他にありますか?それとも私は自分が持っているものに固執する必要がありますか?