2009-08-03 2 views
1

나는 비슷한 질문을 많이했지만 이후에 나는 꽤 답을 찾지 못했습니다. 내 문제의 일부는 속성에서 제네릭을 사용할 수 없기 때문입니다.IList <variableType>; 제너릭없이 해결

나는 아마도 너무 복잡하게하려고 노력하고있다. 그래서 당신이 이것을하는 더 쉬운 방법을 생각할 수 있다면 나는 모두 귀이다.

내 특정 문제는 ASP.NET MVC와 관련이 있으며 동작 메서드에서 특성 (필터)을 사용하고 있습니다. 나는이 같은 ViewData.Model에 전달 된 결과 페이지를 매기는 것이다 필터를 만들려고 해요 :

[PagedList(PageSize = 2, ListType = typeof(Invoice))] 
public ViewResult List() 
{ 
    var invoices = invoicesRepository.Invoices; // Returns an IQueryable<Invoice> 
    return View(Invoices); 
} 

내 필터의 처럼 재정의 다음 보이는 OnActionExecuted : 나는 내가 할 수있는 실현

public override void OnActionExecuted(ActionExecutedContext filterContext) 
{ 
    ViewResult result = (ViewResult)filterContext.Result; 
    var list = (IQueryable<?>)result.ViewData.Model; // Here I want to use the ListType in place of the ? 

    // Perform pagination 
    result.ViewData.Model = list.Skip((Page - 1) * PageSize).Take(PageSize.ToList(); 
} 

대체 내

var list = (IQueryable<?>)result.ViewData.Model; 

으로
var list = (IQueryable)result.ViewData.Model; 
IQueryable<Object> oList = list.Cast<Object>(); 

하지만 내보기는 강하게 당신이 잠재적으로 당신이 다음 내에서해야 할 일을 수행하는 필터의 일반적인 방법을 만들 수있는

IQueryable<Invoice> 

아닌

IQueryable<Object> 

답변

4

을 기대하는 입력 된 OnActionExecuted 리플렉션을 사용하여 ListType이라는 일반 메소드를 호출 하시겠습니까?


편집 : 당신이 게시 된

private void GenericOnActionExecuted<T>(ActionExecutedContext filterContext) 

이 방법은 동일한 코드를 할 것이다 : 예를 들어, 당신이 서명하는 새로운 방법을 만들 것입니다. 그런 다음과 같이 OnActionExecuted를 다시 것입니다 : 내가 알아낼 수있었습니다 당신이 그것을 달성하기 위해 노력하고,이 불가능하기 어려운 범위

public void OnActionExecuted(ActionExecutedContext filterContext) 
{ 
    MethodInfo genericMethod = 
     GetType().GetMethod("GenericOnActionExecuted", 
      BindingFlags.Instance | BindingFlags.NonPublic); 

    MethodInfo constructedMethod = genericMethod.MakeGenericMethod(ListType); 

    constructedMethod.Invoke(this, new object[] { filterContext }); 
} 
+0

필자는 여전히 형식을 어떻게 든 전달해야하며 이는 내가 붙어있는 부분입니다. Type type = typeof (Invoice); //이 속성을 속성으로 전달할 수 있습니다. myNewMethod (); // 그러나 나는 이것을 할 수 없다? – jeef3

+0

일부 예제 코드로 응답을 편집했습니다. – Tinister

+0

예, 완벽합니다. – jeef3

0

에서. 내가 제대로 질문을 이해한다면

, 당신은 이런 식으로 뭔가를 할 싶은 것 :

var someGenericResult = (IQueryable<typeof(SomeType)>)result.ViewData.Model; 

당신은 정보 here를 사용하려고 할 수 있습니다,하지만 당신을 도울 것입니다 경우 모르겠어요 특정 상황에서 인터페이스를 사용하여 정보를 전달할 때 - 그렇듯이 타입 변환 문제는 여전히 남아 있습니다.

+0

감사합니다 andymeadows! 귀하의 링크를 따라하면 그것은 다른 두 것과 같은 방식으로 내 질문에 대답하고있는 것으로 보입니다. 불행히도 나는 단지 하나의 "수락 응답"을 수여 할 수 있습니다 : ( – jeef3

+0

걱정하지 마십시오. 다른 코멘트는 훨씬 자세합니다. 다행 이네요. – andymeadows

1

나는 ASP.NET MVC를 직접 사용하지 않았지만 귀하의 설명에 따라 두 가지 옵션이 있다고 말합니다. 이 두 가지 솔루션 모두 특성에 OnActionExecuted의 일반 버전을 추가해야합니다.

protected void DoActionExecuted<T>(ActionExecutedContext filterContext) 
{ 
    var result = (ViewResult) filterContext.Result; 
    var list = (IQueryable<T>) result.ViewData.Model; 
    result.ViewData.Model = list.Skip((Page - 1)*PageSize) 
           .Take(PageSize) 
           .ToList(); 
} 

당신은 동적 형식 매개 변수와 메소드를 호출하기 위해 사용 반사 중 하나를 수행 할 수 있습니다

public override void OnActionExecuted(ActionExecutedContext filterContext) 
{ 
    GetType().GetMethod("DoActionExecuted", 
         BindingFlags.NonPublic | BindingFlags.Instance) 
      .MakeGenericMethod(ListType) 
      .Invoke(this, new[] {filterContext}); 
} 

또는 당신은 컴파일시에 제네릭 형식에 대해 알고 개인 속성 서브 클래스 만들 수 있습니다

[PagedInvoiceList(PageSize = 2, ListType = typeof (Invoice))] 
public ViewResult List() { ... } 

private class PagedInvoiceListAttribute : PagedListAttribute 
{ 
    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     DoActionExecuted<Invoice>(filterContext); 
    } 
} 
+0

대단히 감사합니다. Nathan! 이것은 Tinister가 제공 한 답변과 동일하지만 나타납니다. 나는 오직 한 사람에게 "Accepted Answer"를 수여 할 수있다. – jeef3

관련 문제