Я являюсь новым в функциональной стороне 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; }
}
};
Этот код производит следующую выровненную по ширине ошибку компилятора:
не может присвоить лямбда-выражение анонимному свойству типа
Код выше установил бы делегата в свойстве 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; }
}
Какие-либо предложения?
Чтобы вызвать анонимную функцию напрямую, это работает:
int result = new Func<int, int>( (int i) =>{ return i + 5; } ).Invoke(3);
// result = 8
Но я согласен, int result = (i => i + 5) (3);
было бы намного круче =)
Компилятор жалуется, потому что вы не вызываете свою лямбда-функцию, вы определяете ее. Если компилятор позволит вам, у вас будет свойство FileName, которое является функцией, а не значением.
Если вы можете написать свою «примитивную логику» в виде выражения, вы можете записать это непосредственно в операторе присваивания.
Насколько я знаю, вы не можете встроить такие лямбда-выражения, потому что лямбда-выражение является самим экземпляром (типа Expression
или аналогичный).
Тем не менее, вы можете сделать это ( обновлено с вычислением 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
, которое позволяет извлечь имя файла из переменной job
непосредственно внутри выражения LINQ.