c# - 使用 LINQ 简化 foreach 循环(在每次迭代中选择两个对象)

标签 c# linq

给定以下接口(interface)和两个类:

public interface IMyObj
{
    int Id { get; set; }
}

public class MyObj1 : IMyObj
{
    public MyObj1(int id) { Id = id; }
    public int Id { get; set; }
    public override string ToString() => $"{GetType().Name} : {Id}";
}

public class MyObj2 : IMyObj
{
    public MyObj2(int id) { Id = id; }
    public int Id { get; set; }
    public override string ToString() => $"{GetType().Name} : {Id}";
}

并给出以下使用它们的逻辑:

var numbers = new[] { 1, 5, 11, 17 };

var list = new List<IMyObj>();

foreach (var n in numbers)
{
    // I'd like to simplify this part with LINQ...
    list.Add(new MyObj1(n));
    list.Add(new MyObj2(n));
}

Assert.AreEqual(8, list.Count);

测试通过,我在 list 中看到了我想要的内容 - 每个数字两个对象实例:

Count = 8
  [0]: {MyObj1 : 1}
  [1]: {MyObj2 : 1}
  [2]: {MyObj1 : 5}
  [3]: {MyObj2 : 5}
  [4]: {MyObj1 : 11}
  [5]: {MyObj2 : 11}
  [6]: {MyObj1 : 17}
  [7]: {MyObj2 : 17}

我的问题是,如何使用 LINQ 简化 foreach 循环逻辑?我认为可能有一种优雅的方式对 SelectMany 做同样的事情也许是运算符,但我无法产生相同的输出。

最佳答案

SelectMany 确实是你想要的:

var list = numbers.SelectMany(n => new IMyObj[] { new MyObj1(n), new MyObj2(n) })
                  .ToList();

换句话说,对于每个数字,创建一个双元素数组,然后使用 SelectMany 将其展平。

new IMyObj[] 部分是必需的,而不仅仅是 new[],因为类型推断无法判断您需要什么数组类型。如果类型相同,您可以执行以下操作:

var list = numbers.SelectMany(n => new[] { new MyObj(n), new MyObj(n) })
                  .ToList();

关于c# - 使用 LINQ 简化 foreach 循环(在每次迭代中选择两个对象),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45960889/

相关文章:

c# - linq 成员不支持 SQL 转换

linq - 使用 Linq 返回最大计数列表

c# - 在动态 Lambda 表达式中获取 Count() 属性

c# - 禁用对位置服务 API 的访问

c# - .NET 私​​钥 Rsa 加密

c# - 列表排序 - 扩展方法未触发!

c# - Resharper,foreach 循环中的 linq

c# - 通过 web.config 转换保护连接字符串的建议方法

c# - 两个 Controller 方法之间不明确

Linq 到 Sql 多对多