首页 > 解决方案 > 如何将自己的方法变成可链接的 LINQ 方法?

问题描述

我有这样的代码,它将数据从输入集合构建为特定格式,并附加一个校验和值:

        var data = input.Aggregate(new List<byte>(), (list, item) =>
        {
            list.Add(item.x);
            list.Add(item.y);
            list.Add(item.bytes.Length);
            list.AddRange(item.bytes);
        });
        data.Add(Checksum(data));
        var bytes = data.ToArray();

我有兴趣将其设为单行,但我看不到如何将当前具有签名的链接链接data到其中。Checksum()byte Checksum(IEnumerable<byte> input)

我以为我可以做类似的事情:

        IEnumerable<byte> AddCheckSum(IList<byte> input)
        {
         return input.Add(Checksum(input));
        }

        var data = input.Aggregate(new List<byte>(), (list, item) =>
        {
            list.Add(item.x);
            list.Add(item.y);
            list.Add(item.bytes.Length);
            list.AddRange(item.bytes);
        }).AddChecksum().ToArray();

但我不知道怎么做。是直截了当吗?

标签: c#.netlinq

解决方案


我怀疑你是否想要AggregateLinqSelectMany使用and似乎更简洁易读Concat

var data = input
  .SelectMany(item => new byte[] {item.x, item.y, item.bytes.Length}.Concat(item.bytes));

var bytes = data
  .Concat(new byte[] {Checksum(data)})
  .ToArray();

但我建议foreach使用明确的解决方案List<byte> data

List<byte> data = new List<byte>();

foreach (var item in input) {
  data.Add(item.x);
  data.Add(item.y);
  data.Add(item.bytes.Length);
  data.AddRange(item.bytes);
} 

data.Add(Checksum(data));

var bytes = data.ToArray();

最后,如果您想一次性计算片段,可以将其包装到扩展方法中:

public static class MyInputExtensions {
  public static byte[] ToBytesWithCheckSum(this IEnumerable<MyInput> input) {
    if (null == input)
      throw new ArgumentNullException(nameof(input));  

    List<byte> data = new List<byte>();

    foreach (var item in input) {
      data.Add(item.x);
      data.Add(item.y);
      data.Add(item.bytes.Length);
      data.AddRange(item.bytes);
    }      

    data.Add(Checksum(data));

    return data.ToArray(); 
  }
}

那么你可以使用ToBytesWithCheckSum()它,就好像它是一种input收集方法:

 byte[] bytes = input.ToBytesWithCheckSum();

推荐阅读