c# - 如何巧妙地从 IEnumerable<T> 创建匿名类型?

标签 c# .net linq collections

我想使用 LINQ 来解决以下问题,我有以下集合:

List<byte> byteList = new List<byte() { 0x01, 0x00, 0x01, 0x02, 0x01, 0x00, 0x3, 0x4, 0x02 };

此示例中的数据遵循以下模式:

byteList[0] = 地址 (1, 2, 3, ... n)

byteList[1] = 旧状态,基本上代表一个枚举

byteList[2] = 新状态,同上

我正在与嵌入式设备交互,这是我查看输入变化的方式。

为了清理代码并使维护程序员更容易遵循我的逻辑,我想抽象出一些涉及的细节并将每个三字节数据集提取为匿名类型以在函数中使用以执行一些额外的处理。我已经编写了一个快速实现,但我相信它可以大大简化。我正在努力清理代码,而不是搅浑水!必须有一种更简单的方法来执行以下操作:

List<byte> byteList = new List<byte>()
{
    0x01, 0x09, 0x01, 0x02, 0x08, 0x02, 0x03, 0x07, 0x03
};
var addresses = byteList
    .Where((b, i) => i % 3 == 0)
    .ToList();
var oldValues = byteList
    .Where((b, i) => i % 3 == 1)
    .ToList();
var newValues = byteList
    .Where((b, i) => i % 3 == 2)
    .ToList();

var completeObjects = addresses
    .Select((address, index) => new 
    { 
        Address = address,
        OldValue = oldValues[index],
        NewValue = newValues[index]
    })
    .ToList();
foreach (var anonType in completeObjects)
{
    Console.WriteLine("Address: {0}\nOld Value: {1}\nNew Value: {2}\n",
        anonType.Address, anonType.OldValue, anonType.NewValue);
}

最佳答案

您可以使用 Enumerable.Range 和一些数学知识:

List<byte> byteList = new List<byte>()
{
    0x01, 0x09, 0x01, 0x02, 0x08, 0x02, 0x03, 0x07, 0x03
};
var completeObjects = Enumerable.Range(0, byteList.Count / 3).Select(index =>
    new
    {
        Address = byteList[index * 3],
        OldValue = byteList[index * 3 + 1],
        NewValue = byteList[index * 3 + 2],
    });

如果字节数不是3的倍数,多出的一两个字节将被忽略。

关于c# - 如何巧妙地从 IEnumerable<T> 创建匿名类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9813499/

相关文章:

c# - 使用 C# 序列化 Java 可反序列化对象

.net - 使用 SpreadsheetGear 将电子表格作为电子邮件附件发送

c# - 如何安装 Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms?

c# - 如何限制 Excel Interop 中的自动筛选仅作用于一列中的行?

c# - 在不知道需要显示的图像数量的情况下,如何在 Windows 窗体应用程序中显示图像?

c# - WebBrowser 控件基本授权标题

c# - WCF 代理使用

c# - 如何使用 EF Core 3.0 使多个包含更高效

c# - 只读集合 IEnumerable

c# - 使用标题 c# 拆分 CSV 文件