我经常对linq感到沮丧,试图建立一个对象并为其添加属性。
示例:
var blgFiles = Directory.GetFiles( rootFolder, "*.blg", SearchOption.AllDirectories );
var data = blgFiles.Select( file => new
{
BLGFile = file,
CSVFile = Path.ChangeExtension( file, "csv" ),
CSVFileExists = File.Exists( CSVFile )
} );
这不会编译,因为我无法在File.Exists中使用CSVFile。
我可以这样做:
CSVFileExists = File.Exists( Path.ChangeExtension( file, "csv" ) )
但这是多余的。
我还可以在我手动复制属性然后添加新属性时进行烦人的多重选择:
var data = blgFiles.Select( file => new
{
BLGFile = file,
CSVFile = Path.ChangeExtension( file, "csv" )
} );
var data2 = data.Select( file => new
{
BLGFile = file.BLGFile,
CSVFile = file.CSVFile,
CSVFileExists = File.Exists( file.CSVFile )
} );
我只是想知道......还有其他方法吗?我正在寻找可以快速添加属性和创建对象的方法,其中某些属性取决于先前属性的值。
答案 0 :(得分:2)
你无能为力。另一种选择:
var data = blgFiles.Select( file =>
{
csvFile = Path.ChangeExtension( file, "csv" );
return new
{
BLGFile = file,
CSVFile = csvFile ,
CSVFileExists = File.Exists( csvFile )
}
});
它还有额外花括号的开销,需要一个显式的return语句,这使得在这个和简化形式之间切换有点麻烦。 (除非你使用Resharper,它会为你做。)
答案 1 :(得分:0)
您可以添加属性并创建对象,其中某些属性取决于先前属性的值",只需要"之前"属性。 对象初始化程序将所有属性设置为一个语句,这就是它的概念。
然而,您可以在select的lambda表达式中创建一个匿名方法,该方法返回您想要的对象。在里面,你可以编写任意C#代码,这将允许你有多个语句,所以你将拥有"之前的#34;的。
编辑:该示例代码已作为答案
答案 2 :(得分:0)
这可能不是您问题的最佳示例,因为您应该生成两个文件列表,并加入它们:
var blgFiles = Directory.GetFiles( rootFolder, "*.blg", SearchOption.AllDirectories );
var csvFiles = Directory.GetFiles( rootFolder, "*.csv", SearchOption.AllDirectories );
var data = blgFiles.GroupJoin(csvFiles,
k=>Path.GetFilenameWithoutExtension(k),
v=>Path.GetFilenameWithoutExtension(v),
(k,g)=>g.Select(v=>new {BLGFILE=k,CSVFILE=v,CSVFileExists=true})
.DefaultIfEmpty(new {BLGFILE=k,CSVFILE=Path.ChangeExtension(k,"csv"),CSVFile=false})
).SelectMany(g=>g);
或使用单个目录查找:
var files=Directory.EnumerateFiles(rootFolder, "*.*", SearchOption.AllDirectories)
.Where(s => s.EndsWith(".blg") || s.EndsWith(".csv"));
然后将它们分组,并生成最终输出。这可能是最快的解决方案,因为磁盘I / O相对昂贵,只做一次这一部分可能会超过任何其他考虑因素。
当然,你总能这样做,但我怀疑你是想避免它:
var blgFiles = Directory.GetFiles( rootFolder, "*.blg", SearchOption.AllDirectories );
var data = blgFiles.Select( file => new
{
BLGFile = file,
CSVFile = Path.ChangeExtension( file, "csv" ),
CSVFileExists = File.Exists(Path.ChangeExtension( file, "csv" ))
} );
但是这将产生大量额外的磁盘I / O,并且两次调用ChangeExtension。还有一个更简单的版本,也有同样的缺陷:
var data = blgFiles.Select( file => new
{
BLGFile = file,
CSVFile = Path.ChangeExtension( file, "csv" )
} ).Select( file => new
{
BLGFile = file.BLGFile,
CSVFile = file.CSVFile,
CSVFileExists = File.Exists( file.CSVFile )
} );