[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public class sTable1Rec
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public char[] Ex_ModelID;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public char[] Field2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public char[] Field3;
}
C#,Reflection
Есть вот такой класс/структура
Код:
точнее подобных классов несколько.
Они используются для чтения записей в некотором "типизированном" файле
Код:
public bool ReadRecord(ref object RecordStruct)
{
int sz = System.Runtime.InteropServices.Marshal.SizeOf(RecordStruct);
if (sz >= (base.Length - base.Position)) return false;
byte[] buf = new byte[sz];
base.Read(buf, 0, buf.Length);
IntPtr ptr = Marshal.AllocHGlobal(sz);
Marshal.Copy(buf, 0, ptr, buf.Length);
Marshal.PtrToStructure(ptr, RecordStruct);
Marshal.FreeHGlobal(ptr);
return true;
}
{
int sz = System.Runtime.InteropServices.Marshal.SizeOf(RecordStruct);
if (sz >= (base.Length - base.Position)) return false;
byte[] buf = new byte[sz];
base.Read(buf, 0, buf.Length);
IntPtr ptr = Marshal.AllocHGlobal(sz);
Marshal.Copy(buf, 0, ptr, buf.Length);
Marshal.PtrToStructure(ptr, RecordStruct);
Marshal.FreeHGlobal(ptr);
return true;
}
Все прекрасно работает...
Далее необходимо сохранить данные в некоторое другое хранилище...
Чтоб не писать на каждую "структуру" свою ф-ю сохранения используя reflection,
"проходимся" по полям класса и получаем оттуда данные
Код:
public void WriteItem(object Item)
{
Type t = Item.GetType();
string s = "";
FieldInfo[] FIList = t.GetFields();
foreach (FieldInfo fi in FIList)
{
if (fi.Name.IndexOf("Ex_", 0, 3) != -1)
{
if (s.Length > 0)
Writer.Write(';');
Writer.Write(fi.GetValue(Item));
}
}
Writer.WriteLine();
}
{
Type t = Item.GetType();
string s = "";
FieldInfo[] FIList = t.GetFields();
foreach (FieldInfo fi in FIList)
{
if (fi.Name.IndexOf("Ex_", 0, 3) != -1)
{
if (s.Length > 0)
Writer.Write(';');
Writer.Write(fi.GetValue(Item));
}
}
Writer.WriteLine();
}
Все прекрасно за исключением одного НО.
Для поля типа char[] ф-я GetValue(Item) возвращает не значение этого поля а строку "System.char[]" — то есть получается тип этого поля.
а как мне получить в итоге значение то этого поля?
если в качестве типа поля использовать string и соответственно UnmanagedType.ByValTStr — все ок, но при чтении проподает один последний прочитанный символ в поле.
Может кто нить предложит другой путь чтения "типизированных" файлов — буду премного благодарен.
Цитата: JShade
Может кто нить предложит другой путь чтения "типизированных" файлов — буду премного благодарен.
Двоичная сериализация с использованием BinaryFormatter - и никакого отражения. Но тогда вы потеряете совместимость с приложением, для которого возможно используете приведенные классы.
Если вы пользуетесь StreamWriter, то все верно - вы получаете System.Char[] на выходе. Это просходит потому, что вызывается метод Write(object a) в котором для записи данных используется ToString метод переданного объекта.
Цитата: hardcase
Двоичная сериализация с использованием BinaryFormatter - и никакого отражения. Но тогда вы потеряете совместимость с приложением, для которого возможно используете приведенные классы.
низзя мне терять совместимость...нужно эту совместимость как раз найти =)
Цитата: hardcase
Если вы пользуетесь StreamWriter, то все верно - вы получаете System.Char[] на выходе. Это просходит потому, что вызывается метод Write(object a) в котором для записи данных используется ToString метод переданного объекта.
Ох дурья ж моя голова!! Нельзя сидеть по 18 часов за компом =)
Вроде ж и ничего сложного....
Спасибо огромное! Вы меня просто спасли! =)