سؤال

أولاً ، مثالان:

// This works
int foo = 43;
long lFoo = foo;

// This doesn't
object foo = (int)43;
long? nullFoo = foo as long?; // returns null
long lFoo = (long)foo; // throws InvalidCastException
if (foo.GetType() == typeof(int))
    Console.WriteLine("But foo is an int..."); // This gets written out

الآن ، تخميني عن سبب عدم عمل الثاني بسبب الملاكمة. الغرض من هذا الرمز هو التنفيذ IComparable. أحتاج إلى طريقة ما لإكراه كائن على إما طويل أو متمرس حسب الاقتضاء ، أو إذا لم يكن كذلك ، بدلاً من إلقاء خطأ. لا أريد أن أضطر إلى تنفيذ الشيكات لكل نوع رقمي أساسي (البايت ، int ، long ، ubyte ، ...) أفضل التقاطها في أكبر نوع رقمي وأتعامل معه بهذه الطريقة. أفكار من جميع الأشخاص الأذكياء هنا؟ كيف يمكنني إلغاء علبة الكائن ، ويفضل أن أتجنب الانعكاس ، لكنني أفترض ما إذا كانت هذه هي الطريقة الوحيدة ... أو يجب ألا أقوم بتنفيذ إصدار غير المائيات من IComparable?

يحرر:

يبدو أن هذا يعمل ، ولكن يبدو وكأنه اختراق مروع حول المشكلة. هل لي فقط؟

long lFoo = long.Parse(foo.ToString());
هل كانت مفيدة؟

المحلول

object foo  = (int) 43;
long   lFoo = ((IConvertible) foo).ToInt64(null);

نصائح أخرى

عندما تصل إلى نوع قيمة ، فأنت تجبر حقًا عملية unbox IL ، الأمر الذي يتطلب أن يكون النوع الذي تقوم بإلقاؤه للمطابقة بالضبط القيمة المعبأة لا توجد تحويلات أو ضمنية أو صريحة يمكن أن تحدث في نفس الوقت.

هذا يعني عادة أنك إما تحتاج إلى إجراء مفتاح باستخدام رمز typecode (أو if/else إذا كنت تستخدم الأنواع) ، أو ، في حالتك ، انتقل مع فحص null متبوعًا بـ Convert.Toint64 () ، والتي يجب أن تتعامل معها بشكل صحيح.

ليس أنت فقط ، ولكن Tryparse لا يثير استثناء.

object foo = (int)43;
long outVal;
if(long.TryParse(foo.ToString(),out outVal))
{
//take action with correct value of long
}
else
{
//maybe passed you another type of object
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top