c# - 适用于 IEnumerable<T> 和 IQueryable<T> 的扩展方法?

标签 c# generics extension-methods

我想要一个适用于我的 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# 规范的规则。

相关博文:

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

编辑:您的想法 行不通,因为无论如何您都不会得到相同的结果类型——如果您调用WhereList<string> 上,返回值不是 List<string> .

可以做的是这样,如果你可以引入一个新的接口(interface)来由 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);
}

关于c# - 适用于 IEnumerable<T> 和 IQueryable<T> 的扩展方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7713326/

相关文章:

c# - 在 C# 中将属性设置为静态是否有任何问题(在多访问的情况下)

c# - 我应该如何组织我的 SharePoint 代码?

generics - 如何在 Scala 中访问泛型类型的类型别名?

c# - 为什么我的扩展方法没有出现在我的测试类中?

c# - 泛型类的扩展方法

c# - 使用 Moq 和 MSTest 测试异常的正确方法

c# - 如何在存在打开的连接时恢复 SQLite 数据库?

c# - 如何为 T[]、T[][] 编写重载的泛型扩展方法而不会产生歧义?

java - 你能解释一下 Java 中装箱和泛型的奇怪行为吗

extension-methods - LINQPad 在扩展方法中访问内置 DataContext