هل هناك طريقة أقل إيلامًا لتجربت لمخزن مؤقت لا تبدأ في 0؟

StackOverflow https://stackoverflow.com/questions/2527018

  •  22-09-2019
  •  | 
  •  

سؤال

يجب أن أتعامل مع البايتات الخام في المشروع وأحتاج إلى القيام بشيء من هذا القبيل بشكل أساسي

byte[] ToBytes(){
  byte[] buffer=new byte[somelength];
  byte[] tmp;
  tmp=BitConverter.GetBytes(SomeShort);
  buffer[0]=tmp[0];
  buffer[1]=tmp[1];
  tmp=BitConverter.GetBytes(SomeOtherShort);
  buffer[2]=tmp[0];
  buffer[3]=tmp[1];
}

أشعر أن هذا خاطئ للغاية ولكن لا يمكنني العثور على طريقة أفضل للقيام بذلك. هل توجد طريقة أسهل؟

هل كانت مفيدة؟

المحلول

BinaryWriter فعال للغاية:

    byte[] ToBytes() {
        var ms = new MemoryStream(somelength);
        var bw = new BinaryWriter(ms);
        bw.Write(SomeShort);
        bw.Write(SomeOtherShort);
        return ms.ToArray();
    }

نصائح أخرى

لا تحتاج إلى التهيئة tmp إلى مجموعة جديدة. BitConverter.GetBytes يخلق مجموعة جديدة ويعيدها لك. ليس هناك الكثير الذي يمكنك فعله حيال ذلك GetBytes ولكن يمكنك استخدام طرق مثل Buffer.BlockCopy لتبسيط عملية النسخ.

إذا كنت لا تفعل ذلك في جزء من الرمز الناقص للأداء ، فيمكنك الذهاب إلى حد ما والقيام بأشياء مثل:

IEnumerable<byte> bytes = BitConverter.GetBytes(first);
bytes = bytes.Concat(BitConverter.GetBytes(second));
bytes = bytes.Concat(BitConverter.GetBytes(third));
// ... so on; you can chain the calls too
return bytes.ToArray();

إذا كنت تعرف الحجم مسبقًا (لديك مجموعة من أنواع القيمة) ، فيمكنك استخدام بنية وتعيين قيمك في البنية. ثم استخدام unsafe رمز لنسخ البايتات الخام. ما زلت ننصح بعدم ذلك إلا إذا كان ذلك ضروريًا لأغراض السرعة. وقد تعتقد أنه مؤلم :)

private struct MyStruct
{
    public short A;
    public short B;

    public MyStruct(short a, short b)
    {
        A = a;
        B = b;
    }
}

private unsafe byte[] UnsafeStruct(MyStruct myStruct)
{
    byte[] buffer = new byte[4]; // where 4 is the size of the struct
    fixed (byte* ptr = buffer)
    {
        *((MyStruct*)ptr) = myStruct;
    }
    return buffer;
}

مجرد حافة بت ...

buffer[0]=(byte)SomeShort;
buffer[1]=(byte)(SomeShort >> 8);
buffer[2]=(byte)SomeOtherShort;
buffer[3]=(byte)(SomeOtherShort >> 8);

هذا يعني أيضًا أنك تتحكم بشكل كامل في Endian-Ness (في هذه الحالة ، Little-Indian)

يمكنك جعل الكود الخاص بك أقصر قليلاً باستخدام Array.copy ، ولكن لا يوجد أي حمولة أو ما يعادلها في BitConverter التي تضع البايتات مباشرة في المخزن المؤقت.

يمكن BinaryWriter على MemoryStream هل ما تريد؟

لاحظ أنه من خلال تبني اتفاقيات API لـ BitConverter التي لا تحبها ، فأنت تسبب نفس المشكلة لمستخدمي فصلك. بدلاً من ذلك ، اكتب طريقة تقبل cwrinicwriter وتسلسل صفك فيها ، وهذا يمتد بشكل جيد عندما يتم تضمين فصلك في بعض الكائنات الأخرى.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top