У меня есть байтовый массив размером около 10 000 байтов, который в основном представляет собой блоб из delphi, который содержит char, string, double и массивы различных типов. Это должно быть прочитано и обновлено через C #.
Я создал очень простую программу чтения, которая получает байтовый массив из базы данных и преобразует байты в соответствующий тип объекта при доступе к свойству, которое работает нормально. Моя проблема в том, что когда я пытаюсь записать определенный элемент char [], он не обновляет байтовый массив. Я создал следующие расширения для чтения и записи:
public static class CharExtension
{
public static byte ToByte( this char c )
{
return Convert.ToByte( c );
}
public static byte ToByte( this char c, int position, byte[] blob )
{
byte b = c.ToByte();
blob[position] = b;
return b;
}
}
public static class CharArrayExtension
{
public static byte[] ToByteArray( this char[] c )
{
byte[] b = new byte[c.Length];
for ( int i = 1; i < c.Length; i++ )
{
b[i] = c[i].ToByte();
}
return b;
}
public static byte[] ToByteArray( this char[] c, int positon, int length, byte[] blob )
{
byte[] b = c.ToByteArray();
Array.Copy( b, 0, blob, positon, length );
return b;
}
}
public static class ByteExtension
{
public static char ToChar( this byte[] b, int position )
{
return Convert.ToChar( b[position] );
}
}
public static class ByteArrayExtension
{
public static char[] ToCharArray( this byte[] b, int position, int length )
{
char[] c = new char[length];
for ( int i = 0; i < length; i++ )
{
c[i] = b.ToChar( position );
position += 1;
}
return c;
}
}
для чтения и записи символов и массивов символов мой код выглядит так:
Byte[] _Blob; // set from a db field
public char ubin
{
get { return _tariffBlob.ToChar( 14 ); }
set { value.ToByte( 14, _Blob ); }
}
public char[] usercaplas
{
get { return _tariffBlob.ToCharArray( 2035, 10 ); }
set { value.ToByteArray( 2035, 10, _Blob ); }
}
Итак, чтобы написать объекты, которые я могу сделать:
ubin = 'C'; // this will update the byte[]
usercaplas = new char[10] { 'A', 'B', etc. }; // this will update the byte[]
usercaplas[3] = 'C'; // this does not update the byte[]
Я знаю, что причина в том, что свойство setter не вызывается, но я хочу знать, есть ли способ обойти это, используя код, аналогичный тому, который у меня уже есть?
Я знаю, что возможным решением является использование закрытой переменной _usercaplas, которую я устанавливаю и обновляю по мере необходимости, однако, поскольку байтовый массив имеет длину почти 10 000 байт, класс уже длинный, и я хотел бы более простой подход, чтобы уменьшить общая длина и сложность кода.
Спасибо
Решение
Вот мое решение, если кто-то захочет. Если у вас есть лучший способ сделать это, дайте мне знать, пожалуйста.
Сначала я создал новый класс для массива:
public class CharArrayList : ArrayList
{
char[] arr;
private byte[] blob;
private int length = 0;
private int position = 0;
public CharArrayList( byte[] blob, int position, int length )
{
this.blob = blob;
this.length = length;
this.position = position;
PopulateInternalArray();
SetArray();
}
private void PopulateInternalArray()
{
arr = blob.ToCharArray( position, length );
}
private void SetArray()
{
foreach ( char c in arr )
{
this.Add( c );
}
}
private void UpdateInternalArray()
{
this.Clear();
SetArray();
}
public char this[int i]
{
get
{
return arr[i];
}
set
{
arr[i] = value;
UpdateInternalArray();
}
}
}
Затем я создал несколько методов расширения, чтобы помочь с преобразованием в байт []
public static byte[] ToByteArray( this CharArrayList c )
{
byte[] b = new byte[c.Count];
for ( int i = 0; i < c.Count; i++ )
{
b[i] = Convert.ToChar( c[i] ).ToByte();
}
return b;
}
public static byte[] ToByteArray( this CharArrayList c, byte[] blob, int position, int length )
{
byte[] b = c.ToByteArray();
Array.Copy( b, 0, blob, position, length );
return b;
}
Итак, чтобы прочитать и написать объекту:
private CharArrayList _usercaplass;
public CharArrayList usercaplas
{
get
{
if ( _usercaplass == null )
_usercaplass = new CharArrayList( _tariffBlob, 2035, 100 );
return _usercaplass;
}
set
{
_usercaplass = value;
_usercaplass.ToByteArray( _tariffBlob, 2035, 100 );
}
}
Как упоминалось ранее, это не идеальное решение, так как мне нужно иметь закрытые переменные и дополнительный код в установщике, но я не мог обойти это.