我有自己的小应用程序来实现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。我想在LINQ语句中添加orderby t.Id
,但由于类型集合包含System.Type
个对象而不是ProblemBase
个对象,因此该属性不可用,我无法转换变量到LINQ查询中的基础对象。我假设它是因为我要求的类型信息在编译时是不知道的,但有没有其他方法可以像查询中的ProblemBase
对象那样对待它?或者我必须坚持我拥有的东西?
答案 0 :(得分: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”塞进原始查询中,因为当时这些项目都不会被创建。