Vra

Gegewe 'n FieldInfo voorwerp en 'n voorwerp, ek moet die werklike grepe voorstelling van die veld te kry. Ek weet dat die veld is óf int,Int32,uint,short ens.

Hoe kan ek die werklike byte verteenwoordiging? BinaryFormatter.Serialize sal nie help nie, aangesien dit my meer inligting as wat ek nodig het sal gee (dit rekords ook tik naam ens). Die Marshal klas lyk nie fasiliteite om grepe skikking gebruik (maar miskien ek mis iets) het.

Dankie

Was dit nuttig?

Oplossing

Jy kan ook kode soos Probeer die volgende as wat jy eintlik wil hê, is om strukture te dra as 'n byte array:

int rawsize = Marshal.SizeOf(value);
byte[] rawdata = new byte[rawsize];
GCHandle handle = GCHandle.Alloc(rawdata, GCHandleType.Pinned);
Marshal.StructureToPtr(value, handle.AddrOfPinnedObject(), false);
handle.Free();

Dit vat die gegewe voorwerp waarde om die byte array Rawdata. Ek het hierdie uit-kode I voorheen geskryf het, en jy mag nodig wees om dit aan te pas by jou behoeftes te maak dit eintlik werk. Ek gebruik dit vir kommunikasie met 'n paar hardeware met die gebruiker-gedefinieerde strukture, maar dit moet werk vir 'n ingeboude tipes sowel (na alles, hulle is strukture, is dit nie?)

Om struktuur lede behoorlik in lyn, gebruik die StructLayout kenmerk om een-byte-belyning spesifiseer:

[StructLayout(LayoutKind.Sequential, Pack = 1)]

En dan gebruik die MarshalAs skryf as wat nodig is vir velde, bv vir inline skikkings:

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
byte[] _state;

Die kode om die struktuur terug te kry uit die byte skikking is iets soos hierdie:

public T GetValue<T>()
{
    GCHandle handle = GCHandle.Alloc(RawValue, GCHandleType.Pinned);
    T structure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), 
                      typeof(T));
    handle.Free();
    return structure;
}

Natuurlik sal jy nodig het om die tipe wat jy wil om dit te laat werk ken.

Let daarop dat dit nie endianness sal hanteer vir homself. In my projek, die meeste veld was net een byte, so dit maak nie saak nie, maar vir die paar lande waar dit gedoen het, het ek net die velde private en openbare eiendom wat sorg sou neem van die endianness ( Jon kleiduiven se skakel van 'n kommentaar op sy antwoord kan jy help, ek het 'n paar nut funksies vir hierdie, want ek net nodig paar).

Wanneer ek hierdie nodig, ek het 'n boodskap klas wat die rou waarde (vandaar die GetValue metode, die kode aan die bokant is eintlik die liggaam van 'n SetValue metode) sou slaan en het 'n paar mooi gerief metode om die waarde geformateerde kry ens.

Ander wenke

Gebruik BitConverter.GetBytes ()

Jy sal eers moet die waarde te omskep dis moedertaal tipe, as gebruik BitConverter om die grepe kry:

byte[] Bytes;

if (valType == typeof(int))
{
    int intVal = (int) GetFieldValue(....);
    Bytes = BitConverter.GetBytes(intVval);
} 
else if (valType == typeof(long))
{
    int lngVal = (long) GetFieldValue(....);
    Bytes = BitConverter.GetBytes(lngVal);
} else ....

Bedoel jy die finaal in-geheue verteenwoordiging? BitConverter.GetBytes (met 'n oorlading paslik deur besinning gekies) sal terugkeer jy n byte verteenwoordiging, maar nie noodwendig wat dit is op die oomblik in die geheue.

Miskien as jy meer inligting oor die rede waarom jy hierdie wil, sal ons beter in staat om jou te help gee.

EDIT: Ek moet byvoeg dat in enige sinvolle saak waaraan ek kan dink, BitConverter sal gee jy dieselfde verteenwoordiging as in die geheue - maar daar mag wees vreemd situasies wat endianness en moontlik vreemd argitektuur met verskillende drywende punt vertoë wat vreemde resultate kan gee.

EDIT: Hier is 'n volledige voorbeeld program wat wys hoe jy kan gaan daaroor:

using System;
using System.Reflection;

public class Test
{
    public int x = 300;

    static void Main()
    {
        Test instance = new Test();
        FieldInfo field = typeof(Test).GetField("x");

        MethodInfo converter = typeof(BitConverter).GetMethod("GetBytes", 
            new Type[] {field.FieldType});

        if (converter == null)
        {
            Console.WriteLine("No BitConverter.GetBytes method found for type "
                + field.FieldType);            
        }
        else
        {
            byte[] bytes = (byte[]) converter.Invoke(null,
                new object[] {field.GetValue(instance) });
            Console.WriteLine("Byte array: {0}", BitConverter.ToString(bytes));
        }        
    }
}
Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top