سؤال

هل هناك أي خطأ في استخدام مشغل ضمني مثل ما يلي:

//linqpad c# program example
void Main()
{
    var testObject = new MyClass<int>() { Value = 1 };

    var add = 10 + testObject; //implicit conversion to int here
    add.Dump(); // 11
}

class MyClass<T>
{
    public T Value { get; set; }
    public static implicit operator T (MyClass<T> myClassToConvert)
    {
        return myClassToConvert.Value;
    }
}

كنت أفكر في أنني يمكن أن أعامل كمثال للكائن كنوع قيمة بهذه الطريقة ، لكنني أرى أنه لم أر مثالًا على هذا الأمر ، فقد اعتقدت أنه ربما كان هناك سبب ليس لفعل شيء كهذا يمكن أن يشير شخص ما؟

في الكود الفعلي الخاص بي ، كنت أفكر في القيام بذلك كجزء من طبقة تجريد البيانات ، حتى أتمكن من إرجاع الكائنات بمعلومات تصف البيانات الأساسية ، ولكن السماح لرمز المنطق بمعاملته كنوع قيمة عندما يحتاج كل ما إلى معرفته هي القيمة ، وفي الوقت نفسه ، احتفظ بكل شيء لطيف وآمن مع الأدوية الجيلية.

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

المحلول

إذا كان كل ما يلي صحيحًا:

  • الكل القيم المحتملة الخاصة بك MyClass<T> الكتابة (بما في ذلك null إذا لم يكن نوع قيمة!) خريطة لقيمة صالحة T

  • المشغل الضمني لا يرمي أبدًا (ولا حتى ل null!)

  • التحويل الضمني له معنى الدلالي ولا يربك المبرمج العميل

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

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


اسمحوا لي أن أعطي مثالاً حيث واجهت مشكلة في تصحيح مشكلة حيث ألقى المشغل الضمني:

public string Foo()
{
    return some_condition ? GetSomething() : null;
}

هنا، GetSomething أعاد شيء من النوع الذي كتبته والذي يحتوي على تحويل ضمني محدد من قبل المستخدم string. لقد صنعت متأكد تماما الذي - التي GetSomething لا يمكن أن تعود أبدا null, ، ومع ذلك حصلت على NullReferenceException! لماذا ا؟ لأن الرمز أعلاه هو ليس أي ما يعادل

return some_condition ? (string)GetSomething() : (string)null;

لكن من أجل

return (string)(some_condition ? GetSomething() : (Something)null);

الآن يمكنك أن ترى أين null جاء من!

نصائح أخرى

هذا نمط رائع. فقط ضع في اعتبارك أنه من أجل استخدامه كمتغير من النوع T, ، يجب عليك إما إلقاءها بشكل صريح T, أو تعيينه لمتغير من النوع T. سيتم إجراء فريق العمل تلقائيًا في مكالمات الطريقة وأشياء أخرى (مثل مثال الإضافة) التي تأخذ أ T.

تحويل ضمني بدون مهمة؟

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