AMcoder - javascript, python, java, html, php, sql

C# - կառուցվածքի սերիականացում

Ես ունեմ մի փոքր դաս, որը ես կցանկանայի օգտագործել կառուցվածքների սերիականացման համար: Ես կցանկանայի իմանալ երկու բան.

  • Կատարման խնդիր. Քանի որ ես անցնում եմ Object - այն անցնում է ընդամենը հղում, այլ ոչ թե կառուցվածքի պատճեն: Եվ քանի որ ես վերադարձնում եմ T տիպի օբյեկտ, այն նաև միայն հղում է փոխանցում:

  • Կոռեկտության խնդիր. Արդյո՞ք այս սերիականացումը կաշխատի բոլոր կառույցների համար: Նկատի ունեմ՝ կա՞ հավանականություն, որ այդ մեթոդները չաշխատեն։

    public static byte[] ToByteArray(Object obj)
    {
        int size = Marshal.SizeOf(obj);
        byte[] arr = new byte[size];
        IntPtr ptr = Marshal.AllocHGlobal(size);
    
        Marshal.StructureToPtr(obj, ptr, true);
        Marshal.Copy(ptr, arr, 0, size);
        Marshal.FreeHGlobal(ptr);
    
        return arr;
    }
    
    public static T ToStructure<T>(byte[] arr) where T : new()
    {
        T str = new T();
    
        int size = Marshal.SizeOf(str);
        IntPtr ptr = Marshal.AllocHGlobal(size);
    
        Marshal.Copy(arr, 0, ptr, size);
        str = (T)Marshal.PtrToStructure(ptr, str.GetType());
        Marshal.FreeHGlobal(ptr);
    
        return str;
    }        
    

Շնորհակալություն, տղաներ:

Խմբագրել

Ես հիմա նշում եմ, որ դրանք կառուցվածքներ են: Հիմա ոչինչ չի՞ պատճենվում:

    public static byte[] ToByteArray<T>(ref T str) where T : struct
    {
        int size = Marshal.SizeOf(str);
        byte[] arr = new byte[size];
        IntPtr ptr = Marshal.AllocHGlobal(size);

        Marshal.StructureToPtr(str, ptr, true);
        Marshal.Copy(ptr, arr, 0, size);
        Marshal.FreeHGlobal(ptr);

        return arr;
    }

    public static T ToStructure<T>(byte[] arr) where T : struct
    {
        T str = default(T);

        int size = Marshal.SizeOf(str);
        IntPtr ptr = Marshal.AllocHGlobal(size);

        Marshal.Copy(arr, 0, ptr, size);
        str = (T)Marshal.PtrToStructure(ptr, str.GetType());
        Marshal.FreeHGlobal(ptr);

        return str;
    }

  • Դուք կարող եք փոխել where T : new()ը where T : structի: Առաջինը կարող է նաև դասեր ընդունել լռելյայն կոնստրուկտորներով, մինչդեռ երկրորդը ավելի մոտ է այն բանին, ինչ դուք նկատի ունեք, և այն նաև ենթադրում է առաջինը, քանի որ բոլոր կառուցվածքները կարող են ինստրուկտացվել default(T)-ի միջոցով: 07.03.2015
  • Լավ, ես խմբագրել եմ հաղորդագրությունը ձեր մեկնաբանությունների հիման վրա: Խնդրում եմ, կասե՞ք, արդյոք դա ճիշտ է հիմա: 07.03.2015
  • Եթե ​​ցանկանում եք ազատվել բռնցքամարտից, տես այս հարցը: 07.03.2015
  • Կարծում եմ, որ այնքան էլ չգիտեմ, որ ձեր հարցին լիարժեք պատասխանեմ, դրա համար էլ մեկնաբանություն եմ թողել։ Ընդհանրապես, հիշեք, որ ամեն անգամ, երբ դուք օգտագործում եք կառուցվածքը որպես հղման տեսակ (դաս/ինտերֆեյս), կա բռնցքամարտ (կույտային տեղաբաշխում և հղում): Նաև հիշեք, որ դաշտերը, որոնք կառավարվող հղումներ են, հավանաբար սերիականացված չեն: 07.03.2015
  • ինչու՞ պարզապես չեք օգտագործում ներկառուցված երկուական սերիալիզացիան: 07.03.2015

Պատասխանները:


1
  1. Սա ճիշտ չի սերիականացնի հղումները (այսինքն՝ ոչ պարզունակ և ոչ կառուցվածքային տիպի որևէ դաշտ):
  2. It doesn't include type data
    • Which makes it unsuitable for cases when not all types are known beforehand or some types have changed slightly since serialization time.
  3. (Փոքր) ToStructure-ը չի հաստատում երկուական տվյալները

Ինչո՞ւ չսովորել առկա լուծումների մասին նախքան անիվը նորից հայտնագործելը: Սերիալացման ուղեցույցներ հոդվածում ասվում է, որ .NET Framework-ում ներդրված են 3 սերիականացման տեխնիկա, որոնք ունեն տարբեր բնութագրեր և հարմարեցված են տարբեր նպատակների համար:

Ահա ամենապարզ, 3-րդ տեխնիկայի օրինակը, որը տրված է որպես օրինակ Օբյեկտների սերիականացման մեջ: .NET հոդված: Այն գոյություն ունի, որպեսզի վերակառուցի օբյեկտը ճիշտ նույն տիպով և ներքին տվյալներով, ինչ բնօրինակը (ինչը նշանակում է, որ սերիականացումը ներառում է այն օբյեկտները, որոնց մասին հղում է կատարում):
(կոդը գտնվում է IronPython-ում, սակայն հուսով եմ, որ այն բավականաչափ ընթեռնելի է հասկանալու համար: ինչ է կատարվում)

>>> l=System.Collections.Generic.List[System.Drawing.Point]\
([System.Drawing.Point(*(random.randint(1,1000) for _ in range(2))) for _ in range(5)])
>>> l
List[Point]([<System.Drawing.Point object at 0x0000000000000233 [{X=491,Y=874}]>
, <System.Drawing.Point object at 0x0000000000000234 [{X=819,Y=595}]>, <System.D
rawing.Point object at 0x0000000000000235 [{X=456,Y=625}]>, <System.Drawing.Poin
t object at 0x0000000000000236 [{X=583,Y=29}]>, <System.Drawing.Point object at
0x0000000000000237 [{X=329,Y=212}]>])
>>> szr=System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
>>> stm=System.IO.MemoryStream()
>>> szr.Serialize(stm,l)
>>> stm.Length
481L
>>> bytes=stm.GetBuffer()
>>> s=''.join(chr(b) for b in bytes)
>>> s
u'\x00\x01\x00\x00\x00\xff\xff\xff\xff\x01\x00\x00\x00\x00\x00\x00\x00\x0c\x02\x
00\x00\x00QSystem.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f
5f7f11d50a3a\x04\x01\x00\x00\x00\x8c\x01System.Collections.Generic.List`1[[Syste
m.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToke
n=b03f5f7f11d50a3a]]\x03\x00\x00\x00\x06_items\x05_size\x08_version\x04\x00\x00\
x16System.Drawing.Point[]\x02\x00\x00\x00\x08\x08\t\x03\x00\x00\x00\x05\x00\x00\
x00\x00\x00\x00\x00\x07\x03\x00\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x04\
x14System.Drawing.Point\x02\x00\x00\x00\x05\xfc\xff\xff\xff\x14System.Drawing.Po
int\x02\x00\x00\x00\x01x\x01y\x00\x00\x08\x08\x02\x00\x00\x00\xeb\x01\x00\x00j\x
03\x00\x00\x01\xfb\xff\xff\xff\xfc\xff\xff\xff3\x03\x00\x00S\x02\x00\x00\x01\xfa
\xff\xff\xff\xfc\xff\xff\xff\xc8\x01\x00\x00q\x02\x00\x00\x01\xf9\xff\xff\xff\xf
c\xff\xff\xffG\x02\x00\x00\x1d\x00\x00\x00\x01\xf8\xff\xff\xff\xfc\xff\xff\xffI\
x01\x00\x00\xd4\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
07.03.2015

2
  1. Կպատճենի։ Սա կոչվում է «բռնցքամարտ»: S կառուցվածքին հղում փոխանցելու միակ միջոցը պարամետր ունենալն է, որը հայտարարված է որպես ref S:
  2. Այն չի մշակում ներդիր նյութեր, ինչպիսիք են զանգվածը, լարը կամ դասի որևէ տեսակ անդամներ:

FYI Ընդհանուր տեղեկություններով դուք կարող եք սահմանափակել մեթոդը, որը պարզապես կիրառելու է կառուցվածքների վրա «where T:struct»-ով:

07.03.2015
Նոր նյութեր

Օգտագործելով Fetch Vs Axios.Js-ը՝ HTTP հարցումներ կատարելու համար
JavaScript-ը կարող է ցանցային հարցումներ ուղարկել սերվեր և բեռնել նոր տեղեկատվություն, երբ դա անհրաժեշտ լինի: Օրինակ, մենք կարող ենք օգտագործել ցանցային հարցումը պատվեր ներկայացնելու,..

Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար
Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար Ինչպե՞ս հանգստացնել ձեր միտքը և աշխատեցնել ձեր պրոցեսորը: Ինչպես մնալ հանգիստ և զարգանալ ճնշման տակ...

Մեքենայի ուսուցում բանկային և ֆինանսների ոլորտում
Բարդ, խելացի անվտանգության համակարգերը և հաճախորդների սպասարկման պարզեցված ծառայությունները բիզնեսի հաջողության բանալին են: Ֆինանսական հաստատությունները, մասնավորապես, պետք է առաջ մնան կորի..

Ես AI-ին հարցրի կյանքի իմաստը, այն ինչ ասում էր, ցնցող էր:
Այն պահից ի վեր, երբ ես իմացա Արհեստական ​​ինտելեկտի մասին, ես հիացած էի այն բանով, թե ինչպես է այն կարողանում հասկանալ մարդկային նորմալ տեքստը, և այն կարող է առաջացնել իր սեփական արձագանքը դրա..

Ինչպես սովորել կոդավորումը Python-ում վագրի պես:
Սովորելու համար ծրագրավորման նոր լեզու ընտրելը բարդ է: Անկախ նրանից, թե դուք սկսնակ եք, թե առաջադեմ, դա օգնում է իմանալ, թե ինչ թեմաներ պետք է սովորել: Ծրագրավորման լեզվի հիմունքները, դրա..

C++-ի օրական բիթ(ե) | Ամենաերկար պալինդրոմային ենթաշարը
C++ #198-ի ամենօրյա բիթ(ե), Ընդհանուր հարցազրույցի խնդիր. Ամենաերկար պալինդրոմային ենթատող: Այսօր մենք կանդրադառնանք հարցազրույցի ընդհանուր խնդրին. Ամենաերկար palindromic substring...

Kydavra ICAReducer՝ ձեր տվյալների ծավալայինությունը նվազեցնելու համար
Ի՞նչ է ICAReducer-ը: ICAReducer-ն աշխատում է հետևյալ կերպ. այն նվազեցնում է նրանց միջև բարձր փոխկապակցված հատկանիշները մինչև մեկ սյունակ: Բավականին նման է PCAreducer-ին, չնայած այն..