الأنواع الخالية والمشغل الثلاثي:لماذا `؟10 :null` ممنوع؟[ينسخ]
-
21-08-2019 - |
سؤال
هذا السؤال لديه بالفعل إجابة هنا:
- تعيين عامل شرطي مع أنواع Nullable<value>؟ 5 إجابات
- لماذا لا يتم تجميع كود C# هذا؟ 4 إجابات
لقد واجهت للتو خطأ غريب:
private bool GetBoolValue()
{
//Do some logic and return true or false
}
ثم بطريقة أخرى مثل هذا:
int? x = GetBoolValue() ? 10 : null;
ببساطة، إذا كانت الطريقة صحيحة، قم بتعيين 10 إلى Nullableint
س.بخلاف ذلك، قم بتعيين قيمة فارغة إلى لاغية كثافة العمليات.ومع ذلك، يشكو المترجم:
خطأ 1 لا يمكن تحديد نوع التعبير الشرطي لأنه لا يوجد تحويل ضمني بين
int
و<null>
.
هل أنا مجنون؟
المحلول
يحاول المترجم أولاً تقييم التعبير الأيمن:
GetBoolValue() ? 10 : null
ال 10
هو int
حرفي (لا int?
) و null
شيء على ما يرام، null
.لا يوجد تحويل ضمني بين هذين ومن هنا تظهر رسالة الخطأ.
إذا قمت بتغيير التعبير الأيمن إلى أحد التعبيرات التالية، فسيتم تجميعه نظرًا لوجود تحويل ضمني بين int?
و null
(رقم 1) وبين int
و int?
(#2, #3).
GetBoolValue() ? (int?)10 : null // #1
GetBoolValue() ? 10 : (int?)null // #2
GetBoolValue() ? 10 : default(int?) // #3
نصائح أخرى
جرب هذا:
int? x = GetBoolValue() ? 10 : (int?)null;
ما يحدث أساسًا هو أن العامل الشرطي غير قادر على تحديد "نوع الإرجاع" للتعبير.نظرًا لأن المترجم يقرر ذلك ضمنيًا 10
هو int
ثم يقرر أن نوع الإرجاع لهذا التعبير يجب أن يكون int
أيضًا.منذ int
لا يمكن null
(المعامل الثالث للعامل الشرطي) يشكو.
عن طريق الصب null
إلى أ Nullable<int>
نحن نقول للمترجم صراحة أن نوع الإرجاع لهذا التعبير يجب أن يكون a Nullable<int>
.كان من الممكن أن تقوم بإلقاء 10
ل int?
كذلك وكان له نفس التأثير.
جرب هذا:
int? result = condition ? 10 : default(int?);
بالمناسبة، فإن تطبيق Microsoft لمترجم C# يخطئ في تحليل نوع العامل الشرطي بطريقة دقيقة جدًا ومثيرة للاهتمام (بالنسبة لي).مقالتي عليه هو اكتب مشاكل الاستدلال، الجزء الأول.
جرب واحدًا مما يلي:
int? x = GetBoolValue() ? (int?)10 : null;
int? x = GetBoolValue() ? 10 : (int?)null;
المشكلة هي أن العامل الثلاثي يستنتج النوع بناءً على تعيين المعلمة الأولى الخاصة بك...10 في هذه الحالة، وهو int، وليس intable.
قد يكون حظك أفضل مع:
int? x = GetBoolValue() (int?)10 : null;
int? x = GetBoolValue() ? 10 : (int?)null;
سبب رؤيتك لهذا هو أنك تستخدم Nullable خلف الكواليس وتحتاج إلى إخبار C# أن "null" الخاص بك هو مثيل فارغ لـ Nullable.
فقط قم بإضافة طاقم تمثيلي واضح.
int? x = GetBoolValue() ? 10 : (int?)null;
إن عامل التشغيل الثلاثي هو الذي يتم الخلط بينه - فالوسيطة الثانية عبارة عن عدد صحيح وكذلك الوسيطة الثالثة من المتوقع أن تكون عددًا صحيحًا أيضًا، ولا يناسبها null.
ذلك لأن المترجم يحدد نوع العامل الشرطي من خلال المعامل الثاني والثالث، وليس من خلال ما تقوم بتعيين النتيجة إليه.لا يوجد تحويل مباشر بين عدد صحيح ومرجع فارغ يمكن للمترجم استخدامه لتحديد النوع.