0

http://projecteuler.netで、問題の解決策を実装するための独自の小さなアプリを入手しました。ProblemBaseID、名前と説明のテキスト、ソルバー関数など、問題に関するメタ情報を含むという名前の基本クラスがあります。すべての問題の実装は、このクラスから派生します。

実装のリストは現在かなり大きくなっているので、ソリューションコンテナーを手動で保守する代わりに、私は初めてリフレクションランドに足を踏み入れました。アイデアは、アセンブリから派生するすべてのタイプを見つけ、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.IdLINQステートメントを追加したいのですが、型コレクションにSystem.TypeオブジェクトではなくProblemBaseオブジェクトが含まれているため、そのプロパティは使用できず、LINQクエリ内で変数をベースオブジェクトに変換できません。要求している型情報がコンパイル時にわからないためだと思いProblemBaseますが、クエリ内からオブジェクトのように扱う方法は他にありますか?それとも私は自分が持っているものに固執する必要がありますか?

4

1 に答える 1

0
var problemTypes = (from t in Assembly.GetAssembly(problemBaseType).GetTypes()
    where t != problemBaseType && problemBaseType.IsAssignableFrom(t)
    select (ProblemBase)Activator.CreateInstance(t)).ToList().OrderBy(t => t.Id);

それはうまくいくのでしょうか?それでもコレクションに追加するにはAddRangeが必要ですが、それはそれらを反復処理しないので問題ありません。私はLINQが得意ではないので、おそらくそれをテストしたいと思うでしょう。

それまでにアイテムが作成されていないため、「orderbyid」を元のクエリに詰め込むことはできないと思います。

于 2013-02-22T23:50:52.573 に答える