C# 模糊易懂<;T>;。Where和IEnumerable<;T>;。扩展方法在哪里
我试图用以下扩展方法覆盖实体的所有Where()方法:C# 模糊易懂<;T>;。Where和IEnumerable<;T>;。扩展方法在哪里,c#,linq,generics,entity-framework-6,extension-methods,C#,Linq,Generics,Entity Framework 6,Extension Methods,我试图用以下扩展方法覆盖实体的所有Where()方法: public static IQueryable<T> Where<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate) { throw new SecurityException("Use the security SafeWhere method"); } public static IQ
public static IQueryable<T> Where<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate)
{
throw new SecurityException("Use the security SafeWhere method");
}
public static IQueryable<T> Where<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate)
where T : IMyInterface
{
throw new SecurityException("Use the security SafeWhere method");
}
公共静态IQueryable Where(此IQueryable源,表达式谓词)
{
抛出新的SecurityException(“使用security-SafeWhere方法”);
}
但是当我使用context.EntitiesX.Where()时,我得到了一个错误:这个调用在Queryable(IQueryable,Expression)和Enumerable(IEnumerable,Expression)之间是不明确的。
我怎样才能解决这个问题?另外,我希望扩展方法只影响实现特定接口的实体,我已经尝试过通过指定接口类型而不是泛型T,但这不起作用。诀窍是赋予扩展方法比第三方(系统)方法更高的优先级 假设您的代码结构是这样的 MyExtensions.cs
using System;
// ... other 3rd party usings
namespace MyExtensionsNamespace
{
public static class MyExtensions
{
public static IQueryable<T> Where<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate)
{
throw new SecurityException("Use the security SafeWhere method");
}
// ...
}
}
using System;
using System.Linq;
// ... other 3rd party usings
using MyExtensionsNamespace;
namespace MyEntitiesNamespace
{
// ...
}
using System;
using System.Linq;
// ... other 3rd party usings
namespace MyEntitiesNamespace
{
using MyExtensionsNamespace;
// ...
}
您所需要的只是在名称空间声明之后移动名称空间using,如下所示
MyEntity.cs
using System;
// ... other 3rd party usings
namespace MyExtensionsNamespace
{
public static class MyExtensions
{
public static IQueryable<T> Where<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate)
{
throw new SecurityException("Use the security SafeWhere method");
}
// ...
}
}
using System;
using System.Linq;
// ... other 3rd party usings
using MyExtensionsNamespace;
namespace MyEntitiesNamespace
{
// ...
}
using System;
using System.Linq;
// ... other 3rd party usings
namespace MyEntitiesNamespace
{
using MyExtensionsNamespace;
// ...
}
另外,编译器错误消息具有误导性。它是在使用扩展方法语法时生成的。对于LINQ语法,错误是不同的
错误CS1940找到源类型“DbSet”的查询模式的多个实现。对“Where”的调用不明确
我还希望扩展方法只影响实现特定接口的实体
尝试在扩展方法上添加常规约束:
public static IQueryable<T> Where<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate)
{
throw new SecurityException("Use the security SafeWhere method");
}
public static IQueryable<T> Where<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate)
where T : IMyInterface
{
throw new SecurityException("Use the security SafeWhere method");
}
公共静态IQueryable Where(此IQueryable源,表达式谓词)
其中T:IMyInterface
{
抛出新的SecurityException(“使用security-SafeWhere方法”);
}
尽管我仍然认为您应该选择一个不同的名称,以避免其他人阅读您的代码时产生任何混淆。解决方法之一是不要将其作为扩展方法编写。将其作为静态方法编写,如下所示
YourClass.Where(context.EntitiesX,…)
我希望确保在其他任何地方都不能覆盖扩展方法。对于编译器来说,它们与静态方法完全相同,当您有两个具有相同签名的方法时,这将导致歧义。重定向Where
扩展方法的目的是什么?如果它只是针对你的实体,为什么不给它一个不同的名称,并彻底消除混淆?“我想确定,没有其他地方的基地正在使用”您无法阻止这一点-您无法阻止某人使用Queryable
扩展方法。可枚举类没有Where
方法和此参数Expression
,因此似乎没有问题namespaces@Grundy我复制了它,名称空间确实在解决这个问题。设置泛型约束并不能解决这个问题,因为在解决最佳重载时没有考虑泛型约束。我想埃里克·利珀特对此发表了一篇文章。唯一的办法是让你的类“更接近”。@IvanStoev这不是我要解决的问题的一部分,也是我建议更改名称的原因。通用约束将解决仅对实现某个接口的成员可用的要求。很抱歉,我以为你在解决整个问题(现在我看到你肯定没有)。