以下声明有什么问题(C#3.0 / Lambda)

时间:2010-05-12 03:28:03

标签: c#-3.0

下面的错误

Enumerable.Range(0, objEntityCode.Count - 1).Select(i => 
{ 
options.Attributes[i] = new EntityCodeKey 
{ 
EntityCode = objEntityCode[i].EntityCodes 
, OrganizationCode = Constants.ORGANIZATION_CODE }; 
})
.ToArray(); 

抛出错误无法从用法推断出方法'System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable,System.Func)'的类型参数。尝试显式指定类型参数。

但这有效

Enumerable.Range(0, objEntityCode.Count - 1).ToList().ForEach(i =>  
                { 
                    options.Attributes[i] = new EntityCodeKey 
                    { 
                         EntityCode = objEntityCode[i].EntityCodes 
                         , OrganizationCode = Constants.ORGANIZATION_CODE   
                    };  

                } 
             ); 

使用C#3.0。

目的:我正在学习LINQ / LAMBDA并尝试以不同的方式执行相同的程序。

感谢。

2 个答案:

答案 0 :(得分:2)

正如我在评论中所说 - 你的lambda表达式不会返回任何内容。因此它不能用于投影。 Select用于将一种类型的项目序列转换为另一种类型的项目序列。你没有在你的lambda表达式中进行任何转换 - 你刚刚完成了一项任务。

现在你可以这样做:

Enumerable.Range(0, objEntityCode.Count - 1).Select(i => 
{ 
    return options.Attributes[i] = new EntityCodeKey 
    { 
        EntityCode = objEntityCode[i].EntityCodes,
        OrganizationCode = Constants.ORGANIZATION_CODE
    }; 
})
.ToArray();

我不会推荐它。我很欣赏你目前正在学习LINQ和lambda表达式,但是当使用它们时,值得学习 - 这看起来像你真的,真的不应该使用它们。

答案 1 :(得分:1)

查看SelectForEach方法调用中的内容:

options.Attributes[i] = new EntityCodeKey 
    { 
        EntityCode = objEntityCode[i].EntityCodes 
        , OrganizationCode = Constants.ORGANIZATION_CODE   
    };

这实际上是一个Action<int> - 也就是某些事情的代码但返回的东西。这就是为什么它在ForEach中有意义但不是Select - Select期望(在这种情况下)Func<int, T> - 代码返回某事(某种类型T)。由于您只是将Attributes[i]分配给新的EntityCodeKey,因此此代码不属于您在Select电话中通常会发现的范围。

注意技术上,上面的代码实际上返回一些东西 - 即存储在options.Attributes[i]中的值 - 如果你从中删除了分号结束。为什么?有两个原因:

  1. 单行lambda表达式(不以分号结尾)返回其计算结果。这就是person => person.Name之类的内容实际上可以解释为Func<Person, string>
  2. 的原因
  3. 赋值操作的计算结果为指定值。这就是您可以撰写x = y = z的原因 - 因为y = z实际上会对新分配的y值进行评估。
  4. 所以这是真的:你的代码,没有分号,实际上会评估为options.Attributes[i]。但是,无论如何,以这种方式编写代码会非常令人困惑。