我是C#功能方面的新手,对不起,如果这个问题很蹩脚。
鉴于以下错误代码:
var jobSummaries = from job in jobs
where ...
select new
{
ID = job.ID,
Description = job.Description,
FileName = (job) => {
// primitive logic not
// worth to become a named method
try { return job.Files[0].LocalName); }
catch { return null as string; }
}
};
此代码产生以下合理的编译器错误:
无法将lambda表达式赋值给 匿名类型属性
上面的代码会将委托设置为FileName属性。但这不是我的目标。我希望代码像这样工作,但没有命名方法:
var jobSummaries = from job in jobs
where ...
select new
{
ID = job.ID,
Description = job.Description,
FileName = this.ExtractFileName(job)
};
...
private string ExtractFileName(Job job)
{
try { return Path.GetFileName(job.Files[0].LocalName); }
catch { return null as string; }
}
有什么建议吗?
答案 0 :(得分:16)
要直接调用匿名函数,这可以:
int result = new Func<int, int>( (int i) =>{ return i + 5; } ).Invoke(3);
// result = 8
但我同意,int result = (i => i + 5)(3);
会更酷...... =
答案 1 :(得分:3)
据我所知,你不能内联这样的lambda表达式,因为lamda表达式本身就是一个实例(类型为Expression<Func<T>>
或类似)。
但是,您可以这样做(通过计算fileName进行更新,因为现在由OP提供):
var jobSummaries = from job in jobs
where ...
let fileName = job.Files.Select(f => f.LocalName).FirstOrDefault()
select new
{
ID = job.ID,
Description = job.Description,
FileName = fileName
};
注意使用let
关键字,它允许您直接从LINQ表达式中的job
变量中提取文件名。
答案 2 :(得分:2)
编译器抱怨是因为你调用你的lambda函数,你定义它。如果编译器允许你,你将拥有一个FileName属性,它是一个函数而不是一个值。
如果您可以将“原始逻辑”编写为表达式,则可以直接在赋值语句中编写它。
答案 3 :(得分:0)
如何使用扩展名进行选择。所以你可以在
中做你的小逻辑var jobSummaries = jobs.Select(j =>
{
var someVar = j + "bla";
return new
{
somelogic = someVar
};
});