2010-03-15 6 views
1

에 :Func을 <sometype, 부울> 내가있는 경우 Func을 <T,bool>

public static Func<SomeType, bool> GetQuery() { 
return a => a.Foo=="Bar"; 
} 

및 제네릭

public static Func<T, bool> GetQuery<T>() { 
return (Func<T,bool>)GetQuery(); 
} 

의 Func을에 SomeType의 내 강력한 형식의 Func을 캐스팅하는 방법이 있나요 티? 내가 지금까지 발견하는 유일한 방법은 시도하고 모의 기능을 결합하는 것입니다 :

Func<T, bool> q=a => true; 
return (Func<T, bool>)Delegate.Combine(GetQuery(), q); 

내가 그 Expression.Lambda와 함께 할 방법을 알고,하지만 난 일반 기능하지 식 트리로 작업해야

편집 - 매튜스 예제를 사용하여 .NET 3.5 을 사용 및 사용의 명시적인 세부 사항.

비록 내가 후에도 그래도 값을 반환 할 때 Func Of concreteType에서 Func Of T로 어떻게 갈 수 있습니까?

필자는 컴파일러 오류가 발생하기를 바라고 있습니다. T가 다른 유형이고 런타임 오류가 발생할 가능성이 높습니다. 저장소에서 그리고 소비

public interface ISecureEntity { 
Func<T,bool> SecureFunction<T>(UserAccount user); 
} 


public class Product : ISecureEntity { 
public Func<T,bool> SecureFunction<T>(UserAccount user) { 
    return (Func<T,bool>)SecureFunction(user); //this is an invalid cast 
} 
public static Func<Product,bool> SecureFunction(UserAccount user) { 
    return f => f.OwnerId==user.AccountId; 
} 
public string Name { get;set; } 
public string OwnerId { get;set; } 
} 


public class ProductDetail : ISecureEntity { 
public Func<T,bool> SecureFunction<T>(UserAccount user) { 
    return (Func<T,bool>)SecureFunction(user); //this is an invalid cast 
} 
public static Func<ProductDetail,bool> SecureFunction(UserAccount user) { 
    return pd => Product.SecureFunction(user)(pd.ParentProduct); 
} 
public int DetailId { get;set; } 
public string DetailText { get;set; } 
public Product ParentProduct { get;set; } 
} 

: 당신이 요구하는, 그러나 여기 어둠 속에서 촬영입니다 무엇 완전히 확실하지 않다

public IList<T> GetData<T>() { 
IList<T> data=null; 
Func<T,bool> query=GetSecurityQuery<T>(); 
using(var context=new Context()) { 
    var d=context.GetGenericEntitySet<T>().Where(query); 
    data=d.ToList(); 
} 
return data; 
} 
private Func<T,bool> GetSecurityQuery<T>() where T : new() { 
    var instanceOfT = new T(); 
     if (typeof(Entities.ISecuredEntity).IsAssignableFrom(typeof(T))) { 
      return ((Entities.ISecuredEntity)instanceOfT).SecurityQuery<T>(GetCurrentUser()); 
     } 
     return a => true; //returning a dummy query 
    } 
} 
+6

불행하게도, 당신이 달성하려고하는지 이해가 안 돼요. –

+0

어떤 버전의 .Net? 여기는 상당히 중요합니다. – Dykam

+0

이 위의 내용을 업데이트하여보다 명확하게되었습니다. .NET 3.5 유형의 SomeType이 될 것입니다 런타임 T에서 Func을 에 Func을 캐스팅하려고하지만 선언하는 인터페이스를 갖고 싶어 사용 : Func을 GetQuery 를(); – steve

답변

2

... 사람들을위한

public interface IFoo 
{ 
    string Foo { get; set; } 
} 
public static Func<T, bool> GetQuery<T>() 
    where T : IFoo 
{ 
    return i => i.Foo == "Bar"; 
} 
// example... 
public class SomeType : IFoo 
{ 
    public string Foo { get; set; } 
} 
public static Func<SomeType, bool> GetQuery() 
{ 
    return GetQuery<SomeType>(); 
} 
+0

달성하려는 목표로 예제를 사용하도록 질문이 업데이트되었습니다. – steve

1

누가이 문제를 겪고 2 가지 부분으로 끝난 해결책을 알고 싶습니까? 위의 도움을 주셔서 감사하고 내 성실성에 대해 질문합니다.

내가 뭘 하려던 것은 표현식을 사용하고 함수를 위임하지 않아야했기 때문입니다. 하위 쿼리/표현식에 문맥을 전달할 수 있도록 대리인 경로 만 보냈습니다.

기존 표현식 (하위 표현식의 일종)에서 변수를 전달할 수있는 표현식을 사용하려면 LinqKit.Invoke를 사용했습니다.

내 최종 클래스는 다음과 같다 :

public interface ISecureEntity { 
Func<T,bool> SecureFunction<T>(UserAccount user); 
} 


public class Product : ISecureEntity { 
public Expression<Func<T,bool>> SecureFunction<T>(UserAccount user) { 
    return SecureFunction(user) as Expression<Func<T,bool>>; 
} 
public static Expression<Func<Product,bool>> SecureFunction(UserAccount user) { 
    return f => f.OwnerId==user.AccountId; 
} 
public string Name { get;set; } 
public string OwnerId { get;set; } 
} 


public class ProductDetail : ISecureEntity { 
public Expression<Func<T,bool>> SecureFunction<T>(UserAccount user) { 
    return SecureFunction(user) as Expression<Func<T,bool>>; 
} 
public static Func<ProductDetail,bool> SecureFunction(UserAccount user) { 
    return pd => Product.SecureFunction(user).Invoke(pd.ParentProduct); 
} 
public int DetailId { get;set; } 
public string DetailText { get;set; } 
public Product ParentProduct { get;set; } 
} 

사용법 :

public IList<T> GetData<T>() { 
IList<T> data=null; 
Expression<Func<T,bool>> query=GetSecurityQuery<T>(); 
using(var context=new Context()) { 
    var d=context.GetGenericEntitySet<T>().Where(query); 
    data=d.ToList(); 
} 
return data; 
} 
private Expression<Func<T,bool>> GetSecurityQuery<T>() where T : new() { 
    var instanceOfT = new T(); 
     if (typeof(Entities.ISecuredEntity).IsAssignableFrom(typeof(T))) { 
      return ((Entities.ISecuredEntity)instanceOfT).SecurityQuery<T>(GetCurrentUser()); 
     } 
     return a => true; //returning a dummy query 
    } 
} 
관련 문제