微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 适用于IEnumerable和IQueryable的扩展方法?

我想要一个适用于我的List和IQueryable的扩展方法.下面的扩展方法实现了这一点,但是如果我添加一个相同的扩展方法,但是在一个不同的完全不相关的类型上我得到了模糊的调用
编译错误.这是为什么?编译器是否足够聪明,无法知道哪种扩展方法有效?我的意思是,这些调用中只有一个是有效的,为什么编译器不能告诉?非常感谢!
class ClassA
{
  public bool IsActive{ get; set;}
}

class ClassB
{
  public bool IsActive { get; set;}
}


// then here are my extensions

public static T IsActive<T>(this T enumerableOrQueryable,bool isActive)
  where T : IEnumerable<ClassA>
{
  return (T)enumerableOrQueryable.Where(x => x.IsActive == isActive);
}

public static T IsActive<T>(this T enumerableOrQueryable,bool isActive)
  where T : IEnumerable<ClassB>
{
  return (T)enumerableOrQueryable.Where(x => x.IsActive == isActive);
}

解决方法

重载规则没有考虑它正在考虑的方法的约束 – 它确定哪个重载是最好的,然后验证约束匹配.

编译器完全遵循C#规范的规则.

相关博文:

> Overloading and generic constraints(我)
> Constraints are not part of the signature(Eric Lippert)
> Evil code – overload resolution workaround(我 – 非常讨厌的东西,但很有趣)

编辑:请注意,使用“enumerableOrQueryable”总是将lambda表达式转换为委托,而不是表达式树.因此,如果您希望它以不同的方式为数据库执行逻辑,那么无论如何都需要进行更改.

编辑:你的想法也行不通,因为你无论如何都不会得到相同的结果类型 – 如果你在列表上调用Where< string>,则返回的值不是List< string>.

如果您可以引入由ClassA和ClassB实现的新接口,那么您可以做到这一点:

public static IQueryable<T> IsActive<T>(this IQueryable<T> source,bool isActive)
    where T : ICanBeActive
{
    // Lambda converted to an expression tree
    return source.Where(x => x.IsActive == isActive);
}

public static IEnumerable<T> IsActive<T>(this IEnumerable<T> source,bool isActive) where T : ICanBeActive
{
    // Lambda converted to a delegate
    return source.Where(x => x.IsActive == isActive);
}

原文地址:https://www.jb51.cc/csharp/92258.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐