0

我有自己的小应用程序,用于在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));
    }

它工作正常,但我想清理一下。现在,我首先创建派生类型的列表,然后将它们实例化到我的集合中,然后再创建另一个集合以按类型对类型进行排序。我想要做的是直接从第一个 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 方面不是最好的,所以你可能想测试一下。

我认为您永远无法将“orderby id”塞入原始查询中,因为届时不会创建项目。

于 2013-02-22T23:50:52.573 回答