我正在研究一种旧的辅助方法,我已经使用了一段时间来将字节数组跟踪到输出。我很久以前写过它,它一直运行良好,但我想知道是否有更好的方法来做到这一点(代码更少)。我想到了 Linq,但我的解决方案非常低效。我需要的是类似于“foreach16”的东西,或者一些枚举器,它不是一次返回一个元素,而是返回一组可枚举的元素。除了我创建自己的枚举器类之外,还有内置的方法吗?
下面的示例包含有关我要完成的工作的更多信息。
原始代码
    static void PrintBytes(byte[] bytes)
    {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.Length; i++)
        {
            if (i > 0 && ((i % 16) == 0))
            {
                // end of line, flushes bytes and resets buffer
                Console.WriteLine("   {0}", sb.ToString());
                sb.Length = 0;
            }
            else if (i > 0 && ((i % 8) == 0))
            {
                Console.Write(" ");
                sb.Append(' ');
            }
            Console.Write(" {0:X2}", (int)bytes[i]);
            if (' ' <= bytes[i] && bytes[i] <= '~')
            {
                sb.Append((char)bytes[i]);
            }
            else
            {
                // non-ASCII or control chars are printed as '.'
                sb.Append('.');
            }
        }
        // flushes the last few bytes
        if ((bytes.Length % 16) > 0)
        {
            // prints spaces where the missing bytes would be
            int spacesToPrint = 3 * (16 - (bytes.Length % 16));
            if ((bytes.Length % 16) <= 8)
            {
                spacesToPrint++;
            }
            Console.Write(new string(' ', spacesToPrint));
        }
        Console.WriteLine("   {0}", sb.ToString());
    }
我现在所拥有的——这是我试图简化代码的。但是我正在做很多 Skip/Take,这将代码的复杂性从线性增加到二次。
    static void PrintBytesV2(byte[] bytes)
    {
        for (int i = 0; i < bytes.Length; i += 16)
        {
            PrintLineV2(bytes, i, Math.Min(16, bytes.Length - i));
        }
    }
    static void PrintLineV2(byte[] array, int offset, int count)
    {
        Console.Write(
            string.Join(
                " ", 
                array
                    .Skip(offset)
                    .Take(count)
                    .Select((b, i) =>
                        ((i == 8) ? " " : "") +
                            string.Format("{0:X2}", (int)b))));
        Console.Write( 
            new string(
                ' ', 
                (16 - count) * 3 +
                    (count <= 8 ? 1 : 0)) + 
            "  ");
        Console.WriteLine(
            string.Join(
            "", 
            array
                .Skip(offset)
                .Take(count)
                .Select(b => (' ' <= b && b <= '~') ? (char)b : '.')));
    }
请注意,即使新代码是线性的,我也可能会坚持使用原始代码,因为 1) 它可以工作;2)我认为它更清晰。但我不禁想知道是否有某种方法可以迭代组。