التغاير (in/out) مع الواجهات والمفوضات
افهم التغاير في C#: استخدم out للمنتجين (التغاير التشاركي) و in للمستهلكين (التغاير العكسي) في الواجهات والمفوضات.
التغاير (in/out) مع الواجهات والمفوضات درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 2 من أصل 3. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 3 دروس في المجموع.
نظرة عامة على التغاير
يتيح التغاير للواجهات والمفوضات العامة العمل مع الوراثة.
- out = التغاير التبايني (منتِج)
- in = التغاير العكسي (مستهلك)
- يكون ذلك آمنًا عندما تنتج واجهة API النوع T فقط أو تستهلكه فقط
عرض توضيحي للتغاير
يتمتع IEnumerable<out T> بالتغاير: يمكن استخدام تسلسل من القطط حيث يُتوقَّع تسلسل من الحيوانات.
using System;
using System.Collections.Generic;
public class Animal { public virtual string Name() { return "animal"; } }
public class Cat : Animal { public override string Name() { return "cat"; } }
public class Program
{
static void PrintAll(IEnumerable<Animal> animals)
{
foreach (Animal a in animals)
{
Console.WriteLine(a.Name());
}
}
public static void Main(string[] args)
{
List<Cat> cats = new List<Cat>();
cats.Add(new Cat());
// IEnumerable<Cat> -> IEnumerable<Animal> is allowed (out T)
PrintAll(cats);
}
}
عرض توضيحي للتغاير العكسي
يتمتع IComparer<in T> بالتغاير العكسي: يعمل مُقارِن لـ Animal أيضًا مع Cat لأنه يستهلك T فقط.
using System;
using System.Collections.Generic;
public class Animal { public string N; public Animal(string n){ N=n; } }
public class Cat : Animal { public Cat(string n) : base(n) {} }
// Comparer can compare any Animals
public class AnimalNameComparer : IComparer<Animal>
{
public int Compare(Animal x, Animal y)
{
return string.Compare(x == null ? "" : x.N, y == null ? "" : y.N, StringComparison.Ordinal);
}
}
public class Program
{
public static void Main(string[] args)
{
List<Cat> cats = new List<Cat>();
cats.Add(new Cat("Miso"));
cats.Add(new Cat("Ada"));
// IComparer<Animal> can be used as IComparer<Cat> (in T)
cats.Sort(new AnimalNameComparer());
foreach (Cat c in cats) Console.WriteLine(c.N);
}
}
تغاير المفوضات
المفوضات متغايرة أيضًا: Func<out TResult> (منتج) وAction<in T> (مستهلك).
using System;
public class Animal { public virtual string Speak(){ return "???"; } }
public class Cat : Animal { public override string Speak(){ return "meow"; } }
public class Program
{
static Animal MakeAnimal() { return new Animal(); }
static void HandleAnimal(Animal a) { Console.WriteLine(a.Speak()); }
public static void Main(string[] args)
{
// Func<Cat> can be used where Func<Animal> is expected? Yes, because TResult is out.
Func<Animal> maker = new Func<Cat>(delegate { return new Cat(); });
Console.WriteLine(maker().Speak());
// Action<Animal> can be used where Action<Cat> is expected? Yes, because T is in.
Action<Cat> catSink = new Action<Animal>(HandleAnimal);
catSink(new Cat());
}
}
واجهات مخصصة ذات تغاير
قاعدة التصميم: ميّز معلمات النوع المخصصة للإنتاج فقط بـ out، والمخصصة للاستهلاك فقط بـ in، لتمكين التحويلات الآمنة.
using System;
// Producer-only interface: out T
public interface ISource<out T>
{
T Get();
}
// Consumer-only interface: in T
public interface ISink<in T>
{
void Put(T item);
}
public class Animal { public string N; }
public class Cat : Animal { }
public class CatSource : ISource<Cat>
{
public Cat Get() { return new Cat(); }
}
public class AnimalSink : ISink<Animal>
{
public void Put(Animal a) { Console.WriteLine("Got animal"); }
}
public class Program
{
public static void Main(string[] args)
{
ISource<Animal> animals = new CatSource(); // out T allows upcast
ISink<Cat> cats = new AnimalSink(); // in T allows down-assign
animals.Get();
cats.Put(new Cat());
}
}
نصائح التغاير
نصائح:
- لا يجوز أن تظهر معلمات out إلا في مواضع الإخراج (أنواع الإرجاع والمواضع المتغايرة).
- لا يجوز أن تظهر معلمات in إلا في مواضع الإدخال (معلمات الأساليب).
- لا تخلط بين الإنتاج والاستهلاك لمعلمة النوع نفسها T عند تعريف التغاير.
- ينطبق التغاير على الواجهات والمفوضات، لا على الفئات.
الكلمة الأساسية للتغاير
مراجعة
مراجعة: استخدم out للمنتجين (التغاير) وin للمستهلكين (التغاير العكسي) في الواجهات والمفوضات. اجعل واجهات API أحادية الاتجاه لتمكين التحويلات الآمنة.
الأسئلة الشائعة
هل درس «التغاير (in/out) مع الواجهات والمفوضات» مجاني؟
نعم — نص درس «التغاير (in/out) مع الواجهات والمفوضات» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 3 دروس في المجموع.
ماذا ستتعلم في «التغاير (in/out) مع الواجهات والمفوضات»؟
افهم التغاير في C#: استخدم out للمنتجين (التغاير التشاركي) و in للمستهلكين (التغاير العكسي) في الواجهات والمفوضات. تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟
لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 3.
كم من الوقت يستغرق درس «التغاير (in/out) مع الواجهات والمفوضات»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟
نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- الأساليب والأنواع العامة؛ القيود
- التغاير (in/out) مع الواجهات والمفوضات
- أنواع المراجع القابلة للقيمة null (للتوعية) والتعليقات التوضيحية (أنماط C# 6)