Aby rozwinąć mój komentarz: musisz użyć IoC (Inversion of Control), aby wstrzyknąć instancję BitConverterEx
tam, gdzie jej potrzebujesz. Ta klasa ma jeden "parametr": endianność wyjścia byte[]
, które będzie czytać/zapisywać.
W końcu problem ten jest podobny do wspólnego problemu „jak mogę kpić DateTime.Now
”
W testach jednostkowych, zamiast wstrzykiwania BitConverterEx
można wstrzyknąć ManipulableBitConverterEx
gdzie można kontrolować flagi procesora. Lub bardziej poprawnie powinieneś przetestować jednostkę niezależnie od BitConverterEx
i swoich klas, aby podczas sprawdzania twoich zajęć wiedzieli, że wyniki BitConverterEx
są poprawne.
public class BitConverterEx
{
public bool ProcessorLittleEndian { get; protected set; }
public bool DataLittleEndian { get; protected set; }
public BitConverterEx(bool dataLittleEndian)
{
ProcessorLittleEndian = BitConverter.IsLittleEndian;
DataLittleEndian = dataLittleEndian;
}
public byte[] GetBytes(int value)
{
byte[] bytes = BitConverter.GetBytes(value);
if (DataLittleEndian != ProcessorLittleEndian)
{
Array.Reverse(bytes);
}
return bytes;
}
public int ToInt32(byte[] value, int startIndex)
{
if (DataLittleEndian == ProcessorLittleEndian)
{
return BitConverter.ToInt32(value, startIndex);
}
byte[] value2 = new byte[sizeof(int)];
Array.Copy(value, startIndex, value2, 0, value2.Length);
Array.Reverse(value2);
return BitConverter.ToInt32(value2, 0);
}
}
public class ManipulableBitConverterEx : BitConverterEx
{
public ManipulableBitConverterEx(bool processorLittleEndian, bool dataLittleEndian)
: base(dataLittleEndian)
{
ProcessorLittleEndian = processorLittleEndian;
}
}
Zauważ, że jeśli trzeba ponownie użyć wielokrotnie tej klasy Array.Reverse
może być „wolnym”. Istnieją rozwiązania odwracające endianię typów danych, które manipulują pojedynczymi bajtami za pomocą shift, lub, xor, ...
Bwahahahahaha ... Nie możesz :-) Ale to jest świetne pytanie! Nawet przy użyciu podróbek, musiałbyś przepisać tyle metod, aby go symulować ... – xanatos
Co powinieneś zrobić: stworzyć klasę otoki wokół BitConvertera, która akceptuje parametr "wymagana endianness" i ma wewnętrzną flagę zawierającą 'BitConverter.IsLittleEndian' które można "zmanipulować" zewnętrznie za pomocą testów jednostkowych. Ta klasa implementuje wszystkie potrzebne metody 'BitConverter', a jeśli' requiredEndianness == savedIsLittleEndian', to znaczy, że używa 'BitConverter', w przeciwnym razie używa' BitConverter + Array.Reverse'. Piszesz testy jednostkowe dla tej klasy i żyjesz szczęśliwy. – xanatos