إصدارات غير الجنيسة من الطبقات الجنيسة واجهات

StackOverflow https://stackoverflow.com/questions/1005913

  •  05-07-2019
  •  | 
  •  

سؤال

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

interface ICanCreate<T>
{
    T NewObject();
}

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

public class Factory
{
    private Dictionary<Type, ICanCreate> mappings; // what do I put here????

    public void RegisterCreator<T>(ICanCreate<T> creator)
    {            
    }

    public T Create<T>()
    {            
    }
}

في القاموس أي نوع يمكنني استخدام لقيمة بلدي؟ أنا لا أعرف إذا أنا في عداد المفقودين نوعا من مبدأ التصميم وأنا على علم بأن هذه لديها الكثير لتفعله مع المشترك (الجهاز؟) التباين. أي مساعدة أو أفكار سيكون محل تقدير كبير.

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

المحلول

واما أن يكون لمجرد استخدام object في إعلان القاموس الخاص بك (كل شيء الخاص، و<م> أنت يمكن التحقق من أن عليك لم يضع الخطأ نوع من شيء في هناك) أو إعلان غير عام واجهة ICanCreate التي تمتد ICanCreate<T>.

وأساسا كنت تريد علاقة النوع الذي لا يمكن التعبير عنها في C # - وكلما حدث ذلك، كنت في نهاية المطاف مع حل غير سارة قليلا، ولكن يبدو أنك يمكن عزل القبح هنا (أي يبقيه ضمن فئة واحدة ).

نصائح أخرى

ومن المثير للاهتمام، وهذا هو المشكلة التي يتم حلها في C # 4.0:

public interface ICanCreate<out T> // covariant
{
    T NewObject();
}

public class Factory
{
    private Dictionary<Type, ICanCreate<object>> mappings = new Dictionary<Type, ICanCreate<object>>();

    public void RegisterCreator<T>(ICanCreate<T> creator) where T:class
    {            
      mappings[typeof(T)] = creator;
    }

    public T Create<T>()
    {            
      ICanCreate<object> creator = mappings[typeof(T)];
      return (T) creator.NewObject(); // I do not think you can get rid of this cast
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top