IsLittleEndian在BitConverter类中的用例是什么?

Ale*_*Aza 8 .net c# vb.net endianness bitconverter

当我发现IsLittleEndian田野时,我很高兴BitConverter.我当然认为它应该在那里,我应该能够指定我喜欢的任何endian.好吧,我的幸福并没有持续多久.花了一些时间才发现没有办法设置场地.该字段是readonly,它只true在静态构造函数中设置:

static BitConverter()
{
    IsLittleEndian = true;
}
Run Code Online (Sandbox Code Playgroud)

有趣的是,该字段实际上是在代码中使用的.例如,ToInt32方法实现如下所示:

if (IsLittleEndian)
{
     return (((numRef[0] | (numRef[1] << 8)) | (numRef[2] << 0x10)) | (numRef[3] << 0x18));
}
return ((((numRef[0] << 0x18) | (numRef[1] << 0x10)) | (numRef[2] << 8)) | numRef[3]);
Run Code Online (Sandbox Code Playgroud)

因此,似乎ToInt32完全有能力处理小端和大端.

我的问题是:为什么有一段非常有用的代码已经实现并且坐在FCL中,但是没有办法使用它(除非你开始搞乱反射当然)?是不是因为一些开发人员没有达到截止日期并且完成了一半的工作?即使如此,为什么代码不可用,但该领域是?我希望这有充分的理由.

我想说清楚.我不需要有关如何处理大端值的解决方案.我确实有一个解决方案.解决方案实际上显示在我的问题中.

gmo*_*979 6

答案在于查看BitConverter 类的参考源。

相关摘录为:

        // This field indicates the "endianess" of the architecture.
        // The value is set to true if the architecture is
        // little endian; false if it is big endian.
#if BIGENDIAN
        public static readonly bool IsLittleEndian /* = false */;
#else
        public static readonly bool IsLittleEndian = true;
#endif
Run Code Online (Sandbox Code Playgroud)

该标志由预处理器指令硬连接,因为为其编译特定版本的框架的体系结构的字节顺序不会改变。


oll*_*llb 5

不幸的是,该IsLittleEndian领域只是通知你.但Jon Skeets MiscUtil库有一个很好的EndianBitConverter,支持小端和大端.还有endian感知的BinaryWriter/-Reader类.

这是链接:http://www.yoda.arachsys.com/csharp/miscutil/

编辑:抱歉,但我没有更好的解释.我认为这应该包含在框架中,我想代码目前在那里,因此很容易将Converter移植到另一个架构.

但是暴露这种功能比仅仅公开这个领域要复杂得多.转换器是静态的,因此更改标志有效地改变了全局状态,并且在多线程场景中这将是灾难性的.要走的路可能是提供两个可以在本地实例化和使用的BitConverter对象(这就是MiscUtil所做的).这需要额外的类和/或接口,因此可能是一个截止日期问题,暂时放弃了.我们希望它能在一段时间后添加.


Ric*_*key 5

首先让我们确定该类BitConverter是专门为本地处理器的位转换设计的。这就是为什么IsLittleEndian是只读的。因此,如果本地处理器是小端,则它不支持与大端相互转换,反之亦然。

虽然我不知道省略对一般字节序的支持的原因,但对我来说最合乎逻辑的原因是performance。一个在整个框架中广泛用于其预期目的(与本机处理器的字节序转换)的类应该尽可能具有性能。通过限制类的通用性,通过限制必须处理的情况来提高其性能。通过仅支持 little-endian,它可能可以更快地测量

好的,现在我们进入问题的关键。如果类的整体设计只打算支持一个,那么作者为什么要包含处理 little-endian 和 big-endian 的代码?

同样,我们只能推测。但答案可能取决于两个观察结果:

  • 所指的反汇编代码在IsLittleEndian 性能方面并不重要
  • 编写可移植的代码,如果不影响性能,是一个很好的软件工程

您从该ToInt32方法复制的代码不重要的原因是因为它仅用于未对齐的内存。99% 的代码路径是位的直接不安全“memcpy”。

即使确实发生了从未对齐的内存转换,处理它的代码的效率也比原始方法低一个数量级。所以额外的条件并不会真正影响性能。

最终结果是:

  • BitConverter类是尽可能高效其有限目的
  • BitConverter尽管如此,其源代码仍可移植到大端处理器架构