سؤال

انا لدي IDataRecord reader أنني أسترجع عشري من كما يلي:

decimal d = (decimal)reader[0];

لسبب ما هذا يلقي استثناءا غير صالح يلقي قائلا أن "المصبوب المحدد غير صالح".

عندما أفعل reader[0].GetType() يخبرني أنه INT32. بقدر ما أعرف، لا ينبغي أن يكون هذا مشكلة ....

لقد اختبرت هذا من قبل هذا القصاص الذي يعمل بشكل جيد فقط.

int i = 3750;
decimal d = (decimal)i;

لقد تركتني هذا خدش رأسي أتساءل لماذا يفشل في إلغاء صندوق UNBORT INT المتضمن في القارئ بمثابة عشري.

هل يعرف أحد لماذا قد يحدث هذا؟ هل هناك شيء دقيق أنا في عداد المفقودين؟

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

المحلول

يمكنك فقط Unbox نوع القيمة بنوعها الأصلي (والنسخة المطلقة لهذا النوع).

بالمناسبة، هذا صحيح (مجرد اختصار لإصدار سطري الخاص بك):

object i = 4;
decimal d = (decimal)(int)i; // works even w/o decimal as it's a widening conversion

لهذا السبب وراء هذا قرأ هذا إدخال بلوق إريك ليبيرت: التمثيل والهوية

شخصيا، أقوم بتصنيف الأشياء التي تم إجراؤها بواسطة بناء جملة يلقي إلى أربعة أنواع مختلفة من العملية (لديهم جميعا تعليمات IL مختلفة):

  1. الملاكمة (box IL التعليمات) و Unboxing (unbox تعليم IL)
  2. صب من خلال التسلسل الهرمي الاحترام (مثل dynamic_cast<Type> في C ++، والاستخدامات castclass تعليمات IL للتحقق)
  3. صب بين أنواع البدائية (مثل static_cast<Type> في C ++، هناك الكثير من تعليمات IL لأنواع مختلفة من المصابيح بين الأنواع البدائية)
  4. استدعاء مشغلي التحويل المحدد للمستخدم (على مستوى IL فهي مجرد طريقة مكالمات إلى المناسبة op_XXX طريقة).

نصائح أخرى

لا توجد مشكلة في الصب int ل decimal, ، ولكن عندما تقوم بتصوير كائن، يجب عليك استخدام النوع الدقيق الذي يحتوي عليه الكائن.

إلى unbox the. int القيمة في decimal القيمة، أنت أولا Unbox أنها كثيرة، ثم يلقي بها إلى عشري:

decimal d = (decimal)(int)reader[0];

تحتوي واجهة Itatarecord أيضا على طرق لإلغاء تحديد القيمة:

decimal d = (decimal)reader.GetInt32(0);

هنا حل بسيط. يعتني بعثة الأمم المتحدة ل Inbumining ثم صب عشرية. عملت بشكل جيد بالنسبة لي.

decimal d = Convert.ToDecimal(reader[0]);  // reader[0] is int

قال مهرد أفشاري ذلك:

يمكنك فقط Unbox نوع القيمة بنوعها الأصلي (والنسخة المطلقة لهذا النوع).

الشيء الذي يدركه هو ذلك هناك فرق بين الصب و Unboxing. وبعد وكان جيريجفل ملاحظة ممتازة

بمعنى أنه من العار أن تبتصر علبة إلغاء وصادر منه نظرة مماثلة، لأنها عمليات مختلفة للغاية.

يصب:

int i = 3750; // Declares a normal int
decimal d = (decimal)i; // Casts an int into a decimal > OK

الملاكمة / unboxing:

object i = 3750; // Boxes an int ("3750" is similar to "(int)3750")
decimal d = (decimal)i; // Unboxes the boxed int into a decimal > KO, can only unbox it into a int or int?
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top