使用Linq to Objects查询可能需要根据函数的结果进行过滤并返回该函数的值。
例如
files.Where(x => string.IsNullOrWhiteSpace(x.getProperty(propName)))
.GroupBy(x => x.getProperty(propName));
编译器是否认识到分组所需的值并保留它?
如果它没有那么必须有一种方法来选择匿名类型并查询Where和GroupBy语句。是否可以使用匿名类型执行此操作?
我可以声明一个类并使用它。
class fileSelector
{
internal string prop;
internal myFile file;
}
var groups = files
.Select(x => new fileSelector() { prop = x.getProperty(propName), file = x })
.Where(x => !string.IsNullOrWhiteSpace(x.prop))
.GroupBy(x => x.prop);
但有没有办法用匿名类型做到这一点?
这是我尝试匿名类型
var groups = files.Select(x => new { x.getProperty(propName), x })
.Where(x => !string.IsNullOrWhiteSpace(x.prop))
.GroupBy(x => x.prop);
但这会产生错误
无效的匿名类型成员声明符。必须使用成员分配,简单名称或成员访问声明匿名类型成员。
最终答案
var groups = files
.Select(x => new { prop = x.getProperty(propName), file = x })
.Where(x => !string.IsNullOrWhiteSpace(x.prop))
.GroupBy(x => x.prop, x => x.file);
答案 0 :(得分:4)
编译器是否认识到分组所需的值并保留它?
不,因为getProperty
可能会产生预期的副作用。
如果它没有那么必须有一种方法来选择匿名类型并查询Where和GroupBy语句。是否可以使用匿名类型执行此操作?
是。只需将new fileSelector() {...}
替换为new {...}
,您的代码就可以按原样运行。但请注意,在您的代码中(以及使用匿名类型的修改版本),分组的元素是fileSelector和匿名类型,而不是myFile。有关如何解决此问题,请参阅Scott Chamberlain's solution。
或者,您可以使用the let
clause来存储中间值:
var groups = from file in files
let prop = file.getProperty(propName)
where !string.IsNullOrWhiteSpace(prop)
group file by prop;
答案 1 :(得分:1)
编译器是否认识到分组所需的值并保留它?
不,它会触摸两次值。
你真正与你的最后一个例子非常接近,你可以使用一个annonamous类型,只需为匿名类型的每个成员命名,然后添加一个元素选择器,使分组的主体{{1属性。
file