2015-11-12 81 views
2

我試圖重寫我的實體具有以下擴展方法都在哪裏()方法:曖昧的IQueryable <T>。凡和IEnumerable <T>。凡在擴展方法

public static IQueryable<T> Where<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate) 
{ 
    throw new SecurityException("Use the security SafeWhere method"); 
} 

但是當我使用上下文。 EntitiesX.Where()我得到的錯誤:電話是可查詢的<TSource>(IQueryable的<TSource>,表達< Func鍵< TSource之間的曖昧,布爾> >)和可數<TSource>(IEnumerable的<TSource>,表達< Func鍵< TSource,布爾> >)

我怎樣才能解決呢?此外,我希望該擴展方法隻影響實現某些接口的實體,我試圖通過指定接口類型,而不是通用的T但這不起作用。

+0

解決的一個辦法就是不要把它寫成擴展方法。把它寫成這樣的靜態方法'YourClass.Where(context.EntitiesX,....)' –

+0

我想確保無處可用基地在哪裏使用 – ferflores

+1

你不能覆蓋擴展方法。對於編譯器來說,它們與靜態方法完全相同,當您有兩個具有相同簽名的方法時,這會導致不明確。 –

回答

1

訣竅是給你的擴展方法比第三方(系統)更高的優先級。

假設你的代碼結構是這樣的

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"); 
     } 
     // ... 
    } 
} 

MyEntity.cs

using System; 
using System.Linq; 
// ... other 3rd party usings 
using MyExtensionsNamespace; 

namespace MyEntitiesNamespace 
{ 
    // ... 
} 

所有你需要的是正確的移動你的命名空間usings在你的命名空間聲明之後,像這樣

MyEntity.cs

using System; 
using System.Linq; 
// ... other 3rd party usings 

namespace MyEntitiesNamespace 
{ 
    using MyExtensionsNamespace; 
    // ... 
} 

附:編譯器錯誤消息是誤導性的。它是在使用擴展方法語法時生成的。對於LINQ語法,錯誤的是不同

Error CS1940 Multiple implementations of the query pattern were found for source type 'DbSet'. Ambiguous call to 'Where'.

+0

Enumerable類沒有帶有'Expression >'這個參數的'Where'方法,所以似乎沒有命名空間的問題 – Grundy

+0

@Grundy我重複了它,名稱空間的確解決了它。 –

0

Also I would like that extension method to only affect entities that implements certain interface,

嘗試把通用約束你的擴展方法:

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

雖然我仍然認爲你應該選擇一個不同的名稱,以避免任何混淆別人閱讀你的代碼。

+1

放置通用約束不能解決問題,因爲解決最佳過載時不考慮通用約束。我認爲Eric Lippert就此發表了一篇文章。唯一的辦法是讓你的班級「更近」。 –

+0

@IvanStoev這不是我正在處理的問題的一部分,爲什麼我建議更改名稱。通用約束_will_解決了僅對實現某個接口的成員可用的要求。 –

+0

我很抱歉,我以爲你正在解決整個問題(現在我看到你當然沒有)。 –