ج # :هل التباين (التباين / التباين) كلمة أخرى لتعدد الأشكال؟

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

سؤال

أحاول معرفة المعنى الدقيق للكلمات Covariance و Contravariance من عدة مقالات وأسئلة عبر الإنترنت حول StackOverflow، ومما أستطيع أن أفهمه، إنه فقط كلمة أخرى لتعدد الأشكال.

هل أنا على صواب مع العبارة أعلاه؟أم أنني فهمت الأمر بشكل خاطئ؟

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

المحلول

من المؤكد أنها مرتبطة بتعدد الأشكال.لن أقول إنها مجرد "كلمة أخرى" لتعدد الأشكال - فهي تتعلق بمواقف محددة للغاية، حيث يمكنك التعامل مع نوع واحد كما لو كان نوعًا آخر في سياق معين.

على سبيل المثال، مع تعدد الأشكال الطبيعي يمكنك التعامل مع أي إشارة إلى أ Banana كمرجع إلى أ Fruit - ولكن هذا لا يعني أنه يمكنك الاستبدال Fruit كل الوقت الذي ترى فيه النوع Banana.على سبيل المثال، أ List<Banana> لا يمكن التعامل معها على أنها List<Fruit> لأن list.Add(new Apple()) صالح ل List<Fruit> ولكن ليس من أجل List<Banana>.

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

من الصعب الخوض في كل التفاصيل في منشور SO واحد (على الرغم من أننا نأمل أن يقوم شخص آخر بعمل أفضل من هذا!).إريك ليبرت لديه مستوى ممتاز سلسلة من المشاركات بلوق حوله.

نصائح أخرى

شكرا لجميع الصيحات، والرجال.

إجابات جون وراسموس جيدة، وأود فقط إضافة ملاحظة فنية سريعة.

عند التحدث بشكل عرضي وغير رسمي، نعم، يستخدم الناس "التباين المشترك" و"التناقض" للإشارة إلى نوع معين من تعدد الأشكال.وهذا هو نوع تعدد الأشكال حيث تتعامل مع سلسلة من العناكب كما لو كانت سلسلة من الحيوانات.

إذا تناولنا علوم الكمبيوتر بالكامل وحاولنا تقديم تعريفات أكثر تقنية، فربما لن أقول إن التغاير والتباين هما "نوع من تعدد الأشكال".أود أن أتناول تعريفًا أكثر تقنية مثل هذا:

أولاً، أود أن أشير إلى أن هناك نوعين محتملين من تعدد الأشكال في لغة C# التي قد تتحدث عنها، ومن المهم عدم الخلط بينهما.

يُطلق على النوع الأول تقليديًا اسم "تعدد الأشكال المخصص"، وهو تعدد الأشكال حيث يكون لديك طريقة M(Animal x)، وتمرر إليها العناكب والزرافات والولب، وتتعامل الطريقة بشكل موحد مع الوسيطات التي تم تمريرها بنفس الطريقة الطريقة باستخدام القواسم المشتركة التي تضمنها فئة الحيوان الأساسية.

يُطلق على النوع الثاني تقليديًا اسم "تعدد الأشكال البارامترية" أو "تعدد الأشكال العام".هذه هي القدرة على صنع طريقة عامة M<T>(T t) ثم احصل على مجموعة من التعليمات البرمجية في الطريقة التي تتعامل مرة أخرى مع الوسيطة بشكل موحد بناءً على القواسم المشتركة التي تضمنها القيود المفروضة على T.

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

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

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

تخيل فئتين:

public class Pet { /*...*/ }
public class Cat:Pet { /*...*/ }

تعدد الأشكال هو القدرة على استخدام أ Cat ك Pet:

void Feed(Pet pet) { /* ... */ }

Cat cat = ...
Feed(cat);

يتم استخدام التباين المشترك والتباين للحديث عن القدرة على استخدام ICollection<Cat> ك ICollection<Pet> (التباين):

void FeedAll(ICollection<Pet> pets) { /* ... */ }

List<Cat> cats = ...
FeedAll(cats);

أو لاستخدام Action<Pet> ك Action<Cat> (التناقض):

Action<Pet> GetFeeder() { /* ... */ }

Action<Cat> feeder = GetFeeder();

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

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

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