ser*_*0ne 5 c# linq compiler-errors dynamic expression-trees
请考虑以下代码,它包含(而不是使用继承的特定原因)实例Dictionary<string, T>和实现IEnumerable,IQueryable以便它可以与linq查询一起使用:
public class LinqTest<T> : IEnumerable<KeyValuePair<string, T>>, IQueryable<KeyValuePair<string, T>>
{
private Dictionary<string, T> items = default(Dictionary<string, T>);
public virtual T this[string key]
{
get { return this.items.ContainsKey(key) ? this.items[key] : default(T); }
set { this.items[key] = value; }
}
public virtual T this[int index]
{
get { return this[index.ToString()]; }
set { this[index.ToString()] = value; }
}
public Type ElementType
{
get { return this.items.AsQueryable().ElementType; }
}
public Expression Expression
{
get { return this.items.AsQueryable().Expression; }
}
public IQueryProvider Provider
{
get { return this.items.AsQueryable().Provider; }
}
public IEnumerator<KeyValuePair<string, T>> GetEnumerator()
{
return this.items.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.items.GetEnumerator();
}
}
Run Code Online (Sandbox Code Playgroud)
我测试了这段代码如下:
LinqTest<dynamic> item = new LinqTest<dynamic>();
item["a"] = 45;
item["b"] = Guid.NewGuid();
item["c"] = "Hello World";
item["d"] = true;
item.Where(o => o.Value.GetType() == typeof(Guid)).ForEach(i => Console.WriteLine(i));
//Compiler error: An expression tree may not contain a dynamic operation
Run Code Online (Sandbox Code Playgroud)
这表明我o.Value.GetType() == typeof(Guid)无法编译成表达式,因为它是dynamic.
但是,我用以下代码测试了这个理论:
Dictionary<string, dynamic> item = new Dictionary<string, dynamic>();
item["a"] = 45;
item["b"] = Guid.NewGuid();
item["c"] = "Hello World";
item["d"] = true;
item.Where(o => o.Value.GetType() == typeof(Guid)).ForEach(i => Console.WriteLine(i));
Run Code Online (Sandbox Code Playgroud)
这个编译,运行没有任何错误,并包含一个动态表达式...任何人都可以解释,并可能指出我如何修复我的代码?
注意: .ForEach是一个实现foreach循环的非标准扩展方法.
问题是你的类型实现了IQueryable<>,所以Queryable方法是通过成员查找选择的 - 所以编译器试图从你的lambda表达式创建一个表达式树...那就是失败了.
字典示例成功,因为它使用Enumerable而不是Queryable,因此它将lambda表达式转换为委托.
您可以使用AsEnumerable以下命令修复代码:
item.AsEnumerable()
.Where(o => o.Value.GetType() == typeof(Guid))
.ForEach(i => Console.WriteLine(i));
Run Code Online (Sandbox Code Playgroud)
目前尚不清楚为什么你要实施IQueryable<>,说实话 - 另一个更简单的选择就是停止这样做.你的源数据只是一个Dictionary,所以已经使用LINQ to Objects而不是任何可查询的...为什么要介绍IQueryable<>呢?
| 归档时间: |
|
| 查看次数: |
6017 次 |
| 最近记录: |