Func <sometype, bool> to Func <T, bool> - PullRequest
       29

Func <sometype, bool> to Func <T, bool>

1 голос
/ 15 марта 2010

Если у меня есть:

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

и общая версия

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

Есть ли способ привести мой строго типизированный Func of SomeType к Func of T? Единственный способ, который я нашел до сих пор, это попытаться объединить его с фиктивной функцией:

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
    }
}

Ответы [ 2 ]

2 голосов
/ 15 марта 2010

Я не совсем уверен, что вы спрашиваете, но вот выстрел в темноте ...

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>();
}
1 голос
/ 18 марта 2010

Для любого, кто сталкивается с этим и хочет знать решение, которое я выбрал, состоит из 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
    }
}
...