سؤال

غريب كيف يمكنني القيام بذلك في C++، ولكن ليس في C#.

لتوضيح الأمر، سألصق الوظيفتين في C++ ثم في C# وأضع علامة على السطور الإشكالية في كود C# بالتعليق "//خطأ".ما تفعله الدالتان هو تشفير المعلمة ثم إضافتها إلى متغير عام يسمى byte1seeds.

هذه هي الوظائف في C++

//Global var:

unsigned char byte1seeds[3];

unsigned long GenerateValue( unsigned long * Ptr )
{
unsigned long val = *Ptr;
for( int i = 0; i < 32; i++ )
    val = (((((((((((val >> 2)^val) >> 2)^val) >> 1)^val) >> 1)^val) >> 1)^val)&1)|((((val&1) << 31)|(val >> 1))&0xFFFFFFFE);
return ( *Ptr = val );
}

void SetupCountByte( unsigned long seed )
{
if( seed == 0 ) seed = 0x9ABFB3B6;
unsigned long mut = seed;
unsigned long mut1 = GenerateValue( &mut );
unsigned long mut2 = GenerateValue( &mut );
unsigned long mut3 = GenerateValue( &mut );
GenerateValue( &mut );
unsigned char byte1 = (mut&0xFF)^(mut3&0xFF);
unsigned char byte2 = (mut1&0xFF)^(mut2&0xFF);
if( !byte1 ) byte1 = 1;
if( !byte2 ) byte2 = 1;
byte1seeds[0] = byte1^byte2;
byte1seeds[1] = byte2;
byte1seeds[2] = byte1;
}

الآن كود C#:

لقد قمت بتغيير الدالة GenerateValue. بدلاً من وجود مؤشر كمعلمة، فإنه يحتوي على معلمة ulong.

للاتصال به وتغيير كلتا القيمتين اللتين أستخدمهما:

  1. ulong mut1 = GenerateValue(mut);
  2. موت = موت1;

فيما يلي الوظائف المترجمة (تم تمييز الأسطر الإشكالية بـ "// خطأ")؛

//Global var:
public static byte[] byte1seeds = new byte[3];

public static ulong GenerateValue(ulong val)
{
    for( int i = 0; i < 32; i++ )
        val = (((((((((((val >> 2)^val) >> 2)^val) >> 1)^val) >> 1)^val) >> 1)^val)&1)|((((val&1) << 31)|(val >> 1))&0xFFFFFFFE);
    return val ;
}

public static void SetupCountByte( uint seed )
{
    if( seed == 0 ) seed = 0x9ABFB3B6;
    ulong mut = seed;
    ulong mut1 = GenerateValue(mut);
    mut = mut1;
    ulong mut2 = GenerateValue(mut);
    mut = mut2;
    ulong mut3 = GenerateValue(mut);
    mut = mut3;
    mut = GenerateValue(mut);
    byte byte1 = (mut & 0xFF) ^ (mut3 & 0xFF); //error
    byte byte2 = (mut1 & 0xFF) ^ (mut2 & 0xFF); //error
    if( byte1 != 0 )
        byte1 = 1;
    if( byte2 != 0 )
        byte2 = 1;
    byte1seeds[0] = byte1^byte2; //error
    byte1seeds[1] = byte2;
    byte1seeds[2] = byte1;
}

الخطأ هو:

لا يمكن تحويل النوع "ulong" ضمنيًا إلى "بايت".يوجد تحويل صريح (هل تفتقد طاقم الممثلين؟)

تحرير: الخطأ في السطر الإشكالي 3 هو:

لا يمكن تحويل النوع "int" إلى "بايت" ضمنيًا.يوجد تحويل صريح (هل تفتقد طاقم الممثلين؟)

وهنا يأتي السؤال:كيفية حل تلك الأخطاء؟

شكرا لك مقدما!

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

المحلول

أضف (byte) ليلقي بها.بما أنك قد تفقد الدقة، عليك أن تخبر المترجم أن القيمة ستناسب البايت، على سبيل المثال.

byte byte1 = (byte)((mut & 0xFF) ^ (mut3 & 0xFF));
byte byte2 = (byte)((mut1 & 0xFF) ^ (mut2 & 0xFF));

نصائح أخرى

هل يمكن أن تفقد المعلومات.لا يسمح المترجم بهذا النوع من العمليات إلا إذا طلبت منه ذلك صراحةً.لذا جرب شيئًا مثل هذا:

byte result = ((byte)mut & 0xFF) ^ ((byte)mut3 & 0xFF);

بهذه الطريقة، يتم إرسال جميع المتغيرات بشكل صريح وستكون النتيجة بايت.أو يمكنك القيام بذلك:

byte result = (byte)((mut & 0xFF) ^ (mut3 & 0xFF));

علامة مرض

يتم تجميع التعليمات البرمجية التالية في C++ ولكن تم رفضها بواسطة مترجم C#، مع عدم توافق نوع تقرير السطر الثالث.

ulong mut = 5;
ulong mut3 = 6;
byte foo = (mut & 0xFF) ^ (mut3 & 0xFF);

توضيح

التعبير (mut & 0xFF) ^ (mut3 & 0xFF) هو من النوع ulong ولا يمكن تعيينه لمتغير من النوع byte.

المتغير mut هو ulong.جميع الأحمال الزائدة & تتطلب تناظر نوع المعامل، وذلك في التعبير (mut & 0xFF), ، القيمة 0xFF تمت ترقيته إلى ulong, ، ونتيجة العملية لها النوع ulong.

في حين أن عملية مماثلة تعطي أيضًا النوع الفرعي الثاني ulong, ، وهذا عرضي لأنه في التعبير الأكبر A ^ B, ، حقيقة هذا التعبير A لديه النوع ulong من شأنه أن يسبب التعبير B ليتم ترقيتها.

وهكذا التعبير (mut & 0xFF) ^ (mut3 & 0xFF) هو من النوع ulong ويتطلب قالبًا صريحًا قبل أن يتم تخصيصه لمتغير من النوع byte.

حل

قم بطباعة التعبير بالكامل بشكل صريح قبل التعيين.

ملاحظات

يقوم الأشخاص بإيقاف تشغيل التحذيرات بدلاً من التفكير فيها لأن معظم مكتبات C+ مليئة بالعيوب.إذا قمت بتبديل التحذيرات مرة أخرى، فستحصل على الكثير منها، ومن غير المجدي محاولة الخوض فيها، على الرغم من أنه في مكان ما من الفوضى ستكون هناك ملاحظة حول تأثير "كان من المحتمل أن يكون هناك حاجة إلى طباعة ضمنية محتملة".

إذا قرأت مواصفات لغة C#، مع إيلاء اهتمام خاص للمشغلين، فسوف تتعلم الكثير من الأشياء المفيدة.على سبيل المثال، سوف يفشل هذا الرمز:

byte b = 0xF0 | 0x0E; //b should contain 0xFE

ولكن هذه سوف تنجح:

byte b1 = (byte)(0xF0 | 0x0E); //typecast fixes it
byte b2 = 0xF0;
b2 |= 0x0E; //reflexive operator typed by target variable

تشير عبارة "يوجد تحويل صريح" إلى أنك تحتاج إلى إجراء تحويل صريح.في هذه الحالة سيكون الأمر مثل:

byte byte1 = (byte) ( (mut & 0xFF) ^ (mut3 & 0xFF) );
byte byte2 = (byte) ( (mut1 & 0xFF) ^ (mut2 & 0xFF) );

هناك مقالة قاعدة معارف MSDN وهذا ما يفسر بعمق الحاجة إلى الإحباط الصريح.الكلمات "يوجد تحويل صريح" في رسالة الخطأ تهدف إلى أن تكون فكرة أنه يجب عليك تحويل نوع البيانات بشكل صريح باستخدام التحويل.في حالتك المحددة، سيبدو الأمر كما يلي:

byte byte1 = (byte) ( (mut & 0xFF) ^ (mut3 & 0xFF) );
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top