反射

2013-02-22 72 views
0

过程中访问的基本类型与LINQ我有我自己的小应用程序在http://projecteuler.net落实的问题的解决方案。我有一个名为ProblemBase的基类,它包含有关这些问题的元信息,例如它们的id,名称和说明文本以及求解器函数。然后,每个问题的实现都来自这个类。反射

实现的列表现在变得相当大,所以不是手动维护溶液容器中,我走进了反映土地的第一次。这个想法是在我的程序集中找到从ProblemBase派生的所有类型,并将它们实例化为应用程序的问题枚举(下面的代码中的​​),以便我可以从我的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
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中最好的,所以你可能想要测试一下。

我不认为你永远可以堵塞你的“排序依据ID”到原始查询的习惯已经由然后创建项目。

+0

工作,我忘记了我可以直接从Select语句做东西。我现在直接从查询返回的列表中创建ObservableCollection。谢谢! :) – 2013-02-23 00:13:37