如何巧妙地从IEnumerable <T>创建一个匿名类型?

Nat*_*ate 4 .net c# linq collections

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

List<byte> byteList = new List<byte() { 0x01, 0x00, 0x01, 0x02, 0x01, 0x00, 0x3, 0x4, 0x02 };
Run Code Online (Sandbox Code Playgroud)

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

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);
}
Run Code Online (Sandbox Code Playgroud)

Mic*_*Liu 5

你可以用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],
    });
Run Code Online (Sandbox Code Playgroud)

如果字节数不是3的倍数,则将忽略额外的一个或两个字节.