سؤال

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

فيما يلي مثال لقد حرصت على إظهار القضية التي أواجهها:

class Program
{
    public static void OutputDateTime(DateTime? datetime)
    {
        Console.WriteLine(datetime);
    }

    public static bool IsDateTimeHappy(DateTime datetime)
    {
        if (DateTime.Compare(datetime, DateTime.Parse("1/1")) == 0)
            return true;

        return false;
    }

    static void Main(string[] args)
    {
        DateTime myDateTime = DateTime.Now;
        OutputDateTime(IsDateTimeHappy(myDateTime) ? null : myDateTime);
        Console.ReadLine();                        ^
    }                                              |
}                                                  |
// This line has the compile issue  ---------------+

على السطر الموضح أعلاه ، أحصل على خطأ التجميع التالي:

لا يمكن تحديد نوع التعبير الشرطي لأنه لا يوجد تحويل ضمني بين "<null>" و "system.dateTime"

أنا مرتبك لأن المعلمة عبارة عن نوع غير قاطع (DateTime؟). لماذا تحتاج إلى التحويل على الإطلاق؟ إذا كان فارغًا ، فاستخدم ذلك ، إذا كان وقت التاريخ ، فاستخدم ذلك.

كنت تحت انطباع أن:

condition ? first_expression : second_expression;

كان هو نفسه:

if (condition)
   first_expression;
else
   second_expression;

من الواضح أن هذا ليس هو الحال. ما السبب خلف هذا؟

(ملاحظة: أعلم أنه إذا قمت بعمل "myDateTime" ، فسيعمل في الوقت المناسب ، فسوف يعمل. ولكن لماذا تحتاجه؟

كما ذكرت سابقًا ، هذا مثال مفتعل. في المثال الحقيقي "MyDatetime" ، قيمة تعين البيانات التي لا يمكن إجراؤها.)

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

المحلول

لا يستنتج المترجم نوع نتيجة المشغل الشرطي من استخدام النتيجة ، ولكن من أنواع وسيطاته. يفشل المترجم عندما يرى هذا التعبير لأنه لا يمكنه استنتاج نوع النتيجة:

IsDateTimeHappy(myDateTime) ? null : myDateTime;

حيث null و DateTime غير متوافق ، تحتاج إلى إخبار المترجم بما يجب أن يكون عليه النوع. يجب أن يقوم المدلى بالخدعة:

DateTime? x = IsDateTimeHappy(myDateTime) ? (DateTime?)null : myDateTime;
OutputDateTime(x);

الآن لن يواجه المترجم أي مشاكل. يمكنك أيضًا كتابة ما سبق على سطر واحد إذا كنت تفضل (لكنني ربما لن أفعل هذا):

OutputDateTime(IsDateTimeHappy(myDateTime) ? (DateTime?)null : myDateTime);

إريك ليبرت لديه اجابة جيدة هذا أيضًا مناسب هنا ويذهب إلى مزيد من التفاصيل حول كيفية تحديد المحول البرمجي الأنواع.

نصائح أخرى

والسبب هو أن المشغل الثلاثية يتوقع أن يكون كل من المعاملات من نفس النوع. يتم وضع المشغل بأكمله قبل تعيينه لنتيجة (في هذه الحالة تم تمريره إلى وظيفة) ، لذلك لا يمكن للمترجم معرفة نوع النتيجة.

IsDateTimeHappy(myDateTime) ? null : myDateTime

في الحالة أعلاه لا يوجد مسار تحويل بين null و DateTime. بمجرد أن تلقي أحدهم DateTime?, ، يمكن للمترجم تحويل الآخر:

IsDateTimeHappy(myDateTime) ? (DateTime?)null : myDateTime
//OR
IsDateTimeHappy(myDateTime) ? null : (DateTime?)myDateTime

يعمل خط القبضة من الكود أعلاه لأنه يمكن للمترجم تحويله DateTime ل DateTime? عبر مشغل تحويل ضمني:

//In Nullable<T>
public static implicit operator T?(T value);

السطر الثاني يعمل بسبب null يمكن تعيينه ل DateTime? لأن هذا الأخير هو نوع مرجعي.

التحويل الضمني غير مسموح به من خلال بيان الإرجاع. إذا كان لديك

if (condition)
    return first_expression;
else
    return second_expression;

ثم تقارن التفاح بالتفاح. وليس لديك أي مشاكل - كما ذكرت.

في حالتك ، يتم تخصيص مساحة كبيرة على المكدس لوقت البيانات - وهو نوع قيمة غير قابل للفرق. لذلك أنت تدلي ببيان لا معنى له للمترجم. إذا قلت ، سأجري لك A أو أ B, ، ثم A و ال B يجب أن تكون نفس الشيء. في حالتك ، B لا يمكن أن يكون أبدا A.

أعتقد أن هذا يتم الرد عليه أيضًا هنا:الأنواع الباطلة والمشغل الثلاثية: لماذا "؟ 10: لاغى؟

أتمنى أن يكون هذا ما تحتاجه. =

ما يقوله المترجم هو:

لو IsDateTimeHappy(myDateTime) هو false, ، ثم أحتاج إلى إرجاع قيمة النوع DateTime يساوي myDateTime. اذا كانت true, ، ثم أحتاج إلى إرجاع قيمة مساوية ل null, ، لكنك لم تخبرني ما هو النوع الذي يجب أن يكون!

لهذا السبب فإن إجابة مارك هي الحل. بعد أن تقدم طاقمًا لإخبار المترجم عن نوع القيمة التي سيتم إرجاعها إذا كانت الحالة true, ، يمكنه التحقق مما إذا كان true و false يمكن تحويل قيم الإرجاع إلى (أو من) نفس النوع.

هتاف مارك! ؛-)

بدلاً من null استعمال default(DateTime?) ثم كلا الجانبين من الثلاثية سيكون لهما أنواع متوافقة.

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