【问题标题】:SelectMany cannot be inferred from the usage [duplicate]无法从用法推断 SelectMany [重复]
【发布时间】:2015-12-16 21:23:20
【问题描述】:

当我尝试编译我的代码时出现以下错误:

方法的类型参数 'System.Linq.Enumerable.SelectMany(System.Collections.Generic.IEnumerable, System.Func>)' 不能从用法中推断出来。尝试指定类型参数 明确的。

        List<RowEntry> entries = ...
        List<RowArgument> arguments = ...

        var argumentsVal = entries.SelectMany((RowEntry entry) =>
            (IEnumerable<RowArgumentVal>)arguments.SelectMany((RowArgument arg) => 
            new RowArgumentVal()
            {
                Action = "X" 
                , EntryID = entry.ID
                , ArgID = arg.ID
                , Val_BIT = true
                , Val_DATE = new DateTime(2014, 01, 04)
                , Val_DATETIME = new DateTime(2014, 01, 04)
                , Val_DECIMAL = 4.6M
                , Val_INT = 88
                , Val_TIME = new TimeSpan(6, 0, 0)
            }
        ).Cast<RowArgumentVal>()).Cast<RowArgumentVal>().ToList();

我不明白如何进一步“输入”这个......

【问题讨论】:

  • SelectMany 旨在获取RowEntry 实例中的子实体列表,而您似乎正在尝试做笛卡尔积?
  • 确实是笛卡尔积。
  • 把内部的SelectMany变成一个简单的Select
  • 只使用Select 而不是SelectMany?

标签: c# linq


【解决方案1】:

问题是内部SelectMany 不适用于那里,您可能指的是Select

var argumentsVal = entries.SelectMany(entry =>
    arguments.Select(arg => new RowArgumentVal())).ToList();

每个entry都会根据arguments映射成一个IEnumerable&lt;RowArgumentVal&gt;

想象外部SelectMany 是一个简单的Select,它会生成List&lt;IEnumerable&lt;RowArgumentVal&gt;&gt;。但是因为它是SelectMany,它会将结果“扁平化”为一个简单的List&lt;RowArgumentVal&gt;

SelectMany 方法需要映射到 IEnumerable&lt;T&gt; - 而不是 T。如果 RowArgumentVal 恰好实现了 IEnumerable&lt;T&gt; 接口,那么您的原始代码将是有效的,我认为情况并非如此。

【讨论】:

    【解决方案2】:

    这似乎是两个列表中的笛卡尔积,因为它们之间没有关系。您可能想加入他们,但不清楚如何加入。

    这是一种生成笛卡尔积的更易读和编译的方法:

    var query = from entry in entries
                from argument in arguments
                select new RowArgumentVal
                {
                   Action = "X", EntryID = entry.ID,  ArgID = argument.ID, // ...
                };
    
    List<RowArgumentVal> argumentsVal = query.ToList();
    

    【讨论】:

      【解决方案3】:

      如果您想要笛卡尔积,请尝试执行以下操作

       var argumentsVal = from e in entries
          from a in arguments
          select new RowArgumentVal(...)
      

      【讨论】:

        【解决方案4】:

        顺便说一句,您可以做的“进一步输入”是将类型参数提供给泛型方法调用。特别是,如果您将第二个 SelectMany 更改为 SelectMany&lt;RowArgument, RowArgumentVal&gt;,您将会收到错误

        无法将类型 RowArgumentVal 隐式转换为 System.Collections.Generic.IEnumerable&lt;RowArgumentVal&gt;。存在显式转换(您是否缺少演员表?)

        无法将 lambda 表达式转换为委托类型 System.Func&lt;RowArgument,int,System.Collections.Generic.IEnumerable&lt;RowArgumentVal&gt;&gt;,因为块中的某些返回类型不能隐式转换为委托返回类型

        这可能会让你得到其他答案——你试图调用一个期望序列的方法,但你给它一个对象。

        (或者在尝试决定添加哪种类型的参数时,您会很快意识到问题所在。)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-30
          • 1970-01-01
          • 2018-11-21
          • 2020-07-31
          • 2014-10-16
          相关资源
          最近更新 更多