通过匿名方法分配匿名类型的属性

时间:2010-03-03 13:17:10

标签: c# lambda anonymous-types anonymous-methods

我是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; }
}

有什么建议吗?

4 个答案:

答案 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
                    };

            });