2013-02-22 1 views
0

http://projecteuler.net의 문제에 대한 솔루션을 구현하기위한 자체 앱이 있습니다. 기본 클래스에 ProblemBase이 있는데, id, name, description 텍스트, solver 함수와 같은 문제에 대한 메타 정보가 들어 있습니다. 모든 문제 구현은이 클래스에서 파생됩니다.리플렉션 중 LINQ를 사용하여 기본 유형에 액세스

구현 목록이 상당히 커지므로 솔루션 컨테이너를 수동으로 유지 관리하는 대신 처음으로 반사 대지에 들어갔다. 아이디어는 내 어셈블리에서 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을 추가하고 싶습니다. 그러나 형식 컬렉션에 ProblemBase 개체 대신 System.Type 개체가 포함되어 있으므로 해당 속성을 사용할 수 없으며 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에서 최고가 아니기 때문에 아마 그것을 테스트하고 싶을 것이다.

그때까지 아이템이 만들어지지 않았기 때문에 "orderby id"를 원래 쿼리에 넣을 수 없을 것이라고 생각합니다.

+0

그 덕분에 Select 문에서 직접 할 수있는 일을 잊어 버렸습니다. 이제 쿼리에서 반환 된 목록에서 ObservableCollection을 직접 만들었습니다. 감사! :) –

관련 문제