【问题标题】:Func<sometype,bool> to Func<T,bool>Func<sometype,bool> 到 Func<T,bool>
【发布时间】:2010-03-15 18:44:50
【问题描述】:

如果我有:

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

还有一个通用版本

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

有没有办法将 SomeType 的强类型 Func 转换为 T 的 Func? 到目前为止我发现的唯一方法是尝试将它与模拟函数结合起来:

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

我知道如何使用 Expression.Lambda,但我需要使用普通函数,而不是表达式树

编辑 - 使用 .net 3.5 使用 Matthews 示例,并附有明确的使用细节。

我仍然追求的是在返回值时如何从 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
    }
}

【问题讨论】:

  • 很遗憾,我不明白你想要完成什么。
  • .Net 的哪个版本?这在这里相当重要。
  • 已在上面更新以更清晰。使用 .net 3.5 尝试将 Func 转换为 Func 在运行时 T 将是 SomeType 类型,但我想要一个声明:Func GetQuery 的接口();
  • 你为什么不给我们一个使用例子,而不是试图找到一些方法不起作用(在你的例子中,T 的唯一有效输入是 Foo。如果你用Doo() as Func&lt;T, bool&gt; 它会编译...但它仍然只能与 Foo 一起使用。
  • 希望额外的细节能更好地解释 - 我试图让事情保持抽象以避免对实现造成混淆 - 但显然情况并非如此,只会造成更多的混乱。

标签: c# lambda anonymous-delegates


【解决方案1】:

我不完全确定你在问什么,但这是在黑暗中的一个镜头......

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>();
}

【讨论】:

  • 更新问题以将您的示例用于我想要实现的目标
【解决方案2】:

对于遇到此问题并想知道我最终得到的解决方案的任何人,有 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
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多