2010-03-16 65 views
5

請注意,_src繼承IQueryable<U>和V繼承new();C#Linq在方法鏈中選擇問題

我寫了下面的語句,沒有語法錯誤。

IQueryable<V> a = from s in _src where (s.Right - 1 == s.Left) select new V(); 

但如果我重新寫了如下,Visual Studio編輯器中的 「選擇」 抱怨錯誤

IQueryable<V> d = _src.Where(s => s.Right - 1 == s.Left).Select(s=> new V()); 

的錯誤是:

The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly. 
Candidates are: 
    System.Collections.Generic.IEnumerable<V> Select<U,V>(this System.Collections.Generic.IEnumerable<U>, System.Func<U,V>) (in class Enumerable) 
    System.Linq.IQueryable<V> Select<U,V>(this System.Linq.IQueryable<U>, System.Linq.Expressions.Expression<System.Func<U,V>>) (in class Queryable) 

誰能解釋這種現象,以及解決方案是如何解決這個錯誤?

===編輯(2010-03-16 5:35 PM)===

感謝邁克兩個。我也嘗試了一個像你這樣的簡單例子。它的工作原理,但這不適用於我的。我貼的代碼如下:

public class NSM<U, V> where U : IQueryable<U> where V : new() 
    { 
    private U _src; 
    public NSM(U source) { _src = source; } 
    public IQueryable<V> LeafNodes 
    { 
     get 
     { 
      return from s in _src where (s.Right - 1 == s.Left) select new V(); 
     } 
    } 
    } 

我想LeafNodes函數被重寫成LINQ方法鏈方法。任何想法?

+0

感謝。第一個等同的陳述是什麼? – Gnought 2010-03-16 09:18:40

+0

您添加的代碼將不會編譯,除非U是具有Right和Left屬性的東西。所以它不能只是'IQueryable ',除非有'where U:ILeftRight'什麼的。 – 2010-03-16 11:17:31

+0

我想通過您的更新樣本得出結論。見下面更新的答案。感謝您提供更多信息。 – 2010-03-16 13:49:44

回答

1

_src是什麼類型?它直接實現IQueryable嗎?我問,因爲我可以得到一個簡單的例子,說明你的工作。

IQueryable<int> ints = Enumerable.Range(4, 12).AsQueryable(); 

IQueryable<decimal> foo = from s in ints where s > 7 select s * 4.2m; 

IQueryable<decimal> bar = ints.Where(s => s > 7).Select(s => s * 4.2m); 

這兩種選擇都適合我。我認爲如果編譯器知道ints(或者在你的情況下是_src)是IQueryable,那麼它會調用正確的重載。或者我完全錯過了什麼?也許我過分簡化了它,並失去了一些細節。

編輯:擴展此以使用新的示例代碼進行一些更改。

訣竅是,Queryable.Select需要一個Expression<Func<X, V>>Enumerable.Select需要Func<X,V>所以,你只需要提供一個Expression版本Select

或從原始代碼

Expression<Func<X,V>> expression = s => new V(); 
IQueryable<V> d = _src.Where(s => s.Right - 1 == s.Left).Select(expression); 
1

錯誤occurres因爲編譯器不能選擇要執行什麼樣的方法:Select擴展方法IEnumerable<T>Select擴展方法IQueryable<T>

1

你碰到的問題是,有在選擇2種不同的用途你的第二個例子,你有適當的使用語句來達到他們兩個。編譯器無法從該語句中找出您想要使用哪一個。您必須使用更專門的呼叫來選擇或刪除不再需要的使用,或以某種其他方式澄清要使用的使用。

+0

如果我將「AsQueryable()」添加到Select中,如下所示: IQueryable d = _src.Where s => s.Right - 1 == s.Left).AsQueryable()。Select(s => new V()); 錯誤也是一樣的。 – Gnought 2010-03-16 09:21:44

0

要解決的模糊編譯器使用AsEnumerable()函數

src.AsEnumerable().Select(s => new V()); 

或者分配給所有的IQueryable

IQueryable<V> x = src.AsEnumerable().Select(s => new V()).AsQueryable(); 
+0

但是這將返回IEnumerable 而不是IQueryable 。沒有改變返回類型的修復程序是什麼? – Gnought 2010-03-16 10:02:54

+0

@必須將其添加到已編輯的帖子中。 – Cornelius 2010-03-16 11:04:58

+0

感謝您的試用。 – Gnought 2010-03-16 16:26:32