سؤال

هذا السؤال لديه بالفعل إجابة هنا:

كنت أعود ASP.NET MVC الدرس وتعلم ذلك ، من أجل التأهل كإجراء لوحدة تحكم ،

  • يجب ألا يكون لها "افتح النوع العام"

أنا أفهم الأثرية إلى حد ما وأستخدمها إلى حد ما ، ولكن:

  • ما هو افتح النوع العام في الشباك.
  • هل هناك شيء مثل أ نوع عام مغلق?
  • افتح النوع العام هو مصطلح غير يستخدم في كثير من الأحيان. ما هو المستخدم / الخلط بينه؟
هل كانت مفيدة؟

المحلول

تحدد لغة C# نوعًا مفتوحًا ليكون نوعًا إما وسيطة نوع أو نوع عام محدد مع وسيطات نوع غير معروفة:

يمكن تصنيف جميع الأنواع كأنواع مفتوحة أو أنواع مغلقة. و النوع المفتوح هو نوع يتضمن معلمات الكتابة. اكثر تحديدا:

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

أ نوع مغلق هو نوع ليس نوعا مفتوحا.

لذلك T, List<T>, ، و Dictionary<string,T>, ، و Dictionary<T,U> كل أنواع مفتوحة (T و U هي حجج الكتابة) في حين List<int> و Dictionary<string,int> هي أنواع مغلقة.

هناك مفهوم ذي صلة: أ نوع عام غير محدود هو نوع عام مع وسيطات نوع غير محددة. لا يمكن استخدام نوع غير محدود في التعبيرات بخلاف typeof() ولا يمكنك إنشاء مثيل لها أو استدعاء أساليبها. على سبيل المثال، List<> و Dictionary<,> هي أنواع غير محدودة.

لتوضيح التمييز الدقيق بين النوع المفتوح ونوع غير محدود:

class Program {
   static void Main() { Test<int>(); }
   static void Test<T>() {
      Console.WriteLine(typeof(List<T>)); // Print out the type name
   }
}

إذا قمت بتشغيل هذا المقتطف ، فسوف يطبع

System.Collections.Generic.List`1[System.Int32]

وهو اسم CLR لـ List<int>. من الواضح في وقت التشغيل أن الوسيطة النوع هي System.Int32. هذا يجعل List<T> أ مقيد النوع المفتوح.

في وقت التشغيل ، يمكنك استخدام الانعكاس لربط وسيطات النوع إلى معلمات النوع غير المحدد لأنواع عامة غير محدودة مع Type.MakeGenericType طريقة:

Type unboundGenericList = typeof(List<>);
Type listOfInt = unboundGenericList.MakeGenericType(typeof(int));
if (listOfInt == typeof(List<int>))
     Console.WriteLine("Constructed a List<int> type.");

يمكنك التحقق مما إذا كان النوع هو نوع عام غير محدود (تعريف النوع العام) التي يمكنك من خلالها بناء أنواع ملزمة مع Type.IsGenericTypeDefinition منشأه:

Console.WriteLine(typeof(Dictionary<,>).IsGenericTypeDefinition); // True
Console.WriteLine(typeof(Dictionary<int,int>).IsGenericTypeDefinition); // False

للحصول على النوع غير المقيد من نوع تم إنشاؤه في وقت التشغيل ، يمكنك استخدام Type.GetGenericTypeDefinition طريقة.

Type listOfInt = typeof(List<int>);
Type list = listOfInt.GetGenericTypeDefinition(); // == typeof(List<>)

لاحظ أنه بالنسبة لنوع عام ، يمكنك إما أن يكون لديك تعريف غير محدود تمامًا ، أو تعريفًا ملزمًا تمامًا. لا يمكنك ربط بعض معلمات النوع وترك الآخرين غير محدودين. على سبيل المثال ، لا يمكن أن يكون لديك Dictionary<int,> أو Dictionary<,string>.

نصائح أخرى

فقط لإضافة:

Dictionary<string, T> (أو أكثر دقة Dictionary<string,>) لا يزال نوعًا مفتوحًا.

مثال:

void Foo<T>(Dictionary<string,T> dic) { ... }

"النوع العام المفتوح" هو مجرد نوع عام لم يحدد بعد نوعه (على سبيل المثال ، CargoCrate<T>). يصبح "مغلقًا" بمجرد تعيين نوع خرساني (على سبيل المثال CargoCrate<Widget>).

على سبيل المثال ، قل أن لديك شيئًا كهذا:

public class Basket<T> {
  T[] basketItems;
}

public class PicnicBlanket<T> {
  Basket<T> picnicBasket;   // Open type here. We don't know what T is.
}

                                 // Closed type here: T is Food.
public class ParkPicnicBlanket : PicnicBlanket<Food> {
}

هنا، picnicBasketنوع s مفتوح: لم يتم تعيين شيء بعد T. عندما تصنع نزهة ملموسة بنوع معين - على سبيل المثال ، عن طريق الكتابة PicnicBlanket<Food> p = new PicnicBlanket<Food>() - نسميها الآن مغلق.

هناك ثلاثة أنواع من الأنواع العامة. لجعله قصيرًا ، في هذا الإعلان (المبسط):

public class Dictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
  • Dictionary<TKey, TValue> هو نوع عام غير محدود.

  • KeyValuePair<TKey, TValue> هو ، في هذه الحالة ، أ فتح نوع عام مبني. يحتوي على بعض المعلمات ، ولكن تم تعريفها بالفعل في مكان آخر (في القاموس ، في هذه الحالة).

  • Dictionary<string, int> سيكون نوع عام مبني مغلق.

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