Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 模糊易懂<;T>;。Where和IEnumerable<;T>;。扩展方法在哪里_C#_Linq_Generics_Entity Framework 6_Extension Methods - Fatal编程技术网

C# 模糊易懂<;T>;。Where和IEnumerable<;T>;。扩展方法在哪里

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

我试图用以下扩展方法覆盖实体的所有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源,表达式谓词)
{
抛出新的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这不是我要解决的问题的一部分,也是我建议更改名称的原因。通用约束将解决仅对实现某个接口的成员可用的要求。很抱歉,我以为你在解决整个问题(现在我看到你肯定没有)。