سؤال

خلفية:

لنفترض أنني حصلت على الفصل التالي:

class Wrapped<T> : IDisposable
{
    public Wrapped(T obj)  { /* ... */ }

    public static implicit operator Wrapped<T>(T obj)
    {
        return new Wrapped<T>(obj);
    }

    public void Dispose()  { /* ... */ }
}

كما ترون ، فإنه يوفر مشغل تحويل نوع ضمني TWrapped<T>. في النهاية ، أود أن أكون قادرًا على استخدام هذا الفصل على النحو التالي:

interface IX  { /* ... */ }

class X : IX  { /* ... */ }

...

IX plainIX = new X();

using (Wrapped<IX> wrappedIX = plainIX)
{
    /* ... */
} 

مشكلة:

ومع ذلك ، فإن تحويل النوع في ما سبق using البند يفشل. بينما يمكنني تعيين ملف new X() مباشرة الى wrappedIX, ، لا يُسمح لي بتعيين أي شيء من النوع IX لذلك. سوف يشكو المترجم بالخطأ التالي:

خطأ البرمجي CS0266: لا يمكن تحويل النوع "ix" ضمنيًا إلى "ملفوفu003CIX> '. يوجد انقلاب صريح (هل تفتقد ممثلين؟)

أنا لا أفهم هذا. ما هي المشكلة هنا؟

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

المحلول

أعتقد أن ذلك بسبب IX هي واجهة. يعتقد المترجم أن قيمة النوع ربما IX يمكن بالفعل اشتقاق من Wrapped<IX> (حتى و إن Wrapped<T> مختومة) لذلك لا يستخدم التحويل.

التفاصيل معقدة للغاية ، في الأقسام 6.4.3 و 6.4.4 من المواصفات C# 3.0. أساسا لأن IX هي واجهة ، إنها ليست "يشملها" أي أنواع ، مما يعني خطوة لاحقة في 6.4.4 فشل.

أقترح عليك إنشاء نوع غير عام Wrapped مع هذه الطريقة:

public static Wrapped<T> Of<T>(T item)
{
    return new Wrapped<T>(item);
}

ثم يمكنك الكتابة فقط:

using (Wrapped<IX> wrappedIX = Wrapped.Of(plainIX))

يمكن أن تكون التحويلات صعبة بعض الشيء لأسباب مختلفة - الأساليب البسيطة أسهل بشكل عام فهمها ، IMO.

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