C#Linq选择方法链中的问题

Gno*_*ght 5 c# linq select selector

注意_src继承IQueryable<U>和V继承new();

我写了以下语句,没有语法错误.

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

但如果我按如下方式重写它,Visual Studio编辑器会在"选择"中抱怨错误

IQueryable<V> d = _src.Where(s => s.Right - 1 == s.Left).Select(s=> new V());
Run Code Online (Sandbox Code Playgroud)

错误是:

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)
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释这种现象,解决错误的方法是什么?

===编辑(2010-03-16 5:35 pm)===

谢谢Mike Two.我也尝试了一个像你这样的简单例子.它可以工作,但这不是我的.我发布的代码如下:

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();
        }
    }
  }
Run Code Online (Sandbox Code Playgroud)

我希望将LeafNodes函数重写为linq方法链方法.任何的想法?

Mik*_*Two 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 );
Run Code Online (Sandbox Code Playgroud)

这两个选择都适合我。我认为如果编译器知道 ints (或者在你的情况下 _src)是一个 IQueryable 那么它会调用正确的重载。或者我完全错过了什么?也许我过于简单化了,丢失了一些细节。

编辑:扩展它以使用新的示例代码并进行一些更改。

诀窍是Queryable.Select需要一个Expression<Func<X, V>>并且Enumerable.Select需要一个Func<X,V>所以你只需要提供一个Expression版本Select

public interface ILeftRight
{
    int Right { get;}
    int Left { get; }
}

public class NSM<X, U, V> where U : IQueryable<X> where X : ILeftRight where V : new()  
{
    private readonly 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();
            Expression< Func< X, V > > expression = s => new V();
            return _src.Where( s => s.Right - 1 == s.Left ).Select( expression );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

或者从原始代码

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