这是一种方法,但这是否符合要求……谁知道呢。cpu字节序重要吗?
public struct ION
{
public Single a0 ;
public Single a1 ;
public Single a2 ;
public Single a3 ;
public Single b0 ;
public Single b1 ;
public Single b2 ;
public Single b3 ;
public Double A1 ;
public Double A0 ;
public UInt32 Tot ;
public Int16 Wnt ;
public Int16 DtLS ;
public Int16 WnLSF ;
public Int16 DN ;
public Int16 DtLSF ;
public Int16 Wn ;
public UInt32 Tow ;
public Int16 bulwn ;
public UInt32 bultow ;
public UInt16 checksum
{
get
{
byte[][] raw =
{
BitConverter.GetBytes( a0 ) ,
BitConverter.GetBytes( a1 ) ,
BitConverter.GetBytes( a2 ) ,
BitConverter.GetBytes( a3 ) ,
BitConverter.GetBytes( b0 ) ,
BitConverter.GetBytes( b1 ) ,
BitConverter.GetBytes( b2 ) ,
BitConverter.GetBytes( b3 ) ,
BitConverter.GetBytes( A1 ) ,
BitConverter.GetBytes( A0 ) ,
BitConverter.GetBytes( Tot ) ,
BitConverter.GetBytes( Wnt ) ,
BitConverter.GetBytes( DtLS ) ,
BitConverter.GetBytes( WnLSF ) ,
BitConverter.GetBytes( DN ) ,
BitConverter.GetBytes( DtLSF ) ,
BitConverter.GetBytes( Wn ) ,
BitConverter.GetBytes( Tow ) ,
BitConverter.GetBytes( bulwn ) ,
BitConverter.GetBytes( bultow ) ,
} ;
byte[] cooked = raw.SelectMany( x => x ).ToArray() ;
uint accumulator = 0 ;
for ( int i = 0 ; i < cooked.Length ; i+= 2 )
{
ushort value = BitConverter.ToUInt16( cooked , i ) ;
accumulator += value ;
}
return (ushort) accumulator ;
}
}
}
或者您可以下拉到不安全的代码并执行以下操作:
public UInt16 checksum
{
get
{
uint accumulator = 0 ;
unsafe
{
fixed ( ION* x = &this )
{
for ( ushort *p = (ushort*) x ; p < x+1 ; ++p )
{
accumulator += *p ;
}
}
}
return (ushort) accumulator ;
}
}
但是,如果结构中或结构末尾有任何填充,我不相信您可以保证填充八位字节为零,因此您的结果可能会受到影响。如果你的结构包含奇数个八位字节,你可能会抛出一个异常,试图读取结构的末尾......或计算一个不正确的值。
当然,您可以将结构序列化为内存流,然后将其作为 ushort 流读取:
public UInt16 checksum
{
get
{
uint accumulator = 0 ;
using ( BinaryReader reader = new BinaryReader( new MemoryStream() ) )
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize( reader.BaseStream , this ) ;
reader.BaseStream.Seek(0,SeekOrigin.Begin) ;
while ( reader.BaseStream.Position < reader.BaseStream.Length )
{
ushort value = reader.ReadUInt16() ;
accumulator += value ;
}
}
return (ushort) accumulator ;
}
}
但同样,这是对布局、字节顺序和填充的假设。如果结构大小是奇数,你几乎肯定会抛出异常。