سؤال

هل يمكن لأحد يشرح السلوك التالي؟

باختصار، إذا قمت بإنشاء متعددة cls متوافقة. المكتبات في Visual Studio 2008 وحصلت عليهم بمشاركة جذر مساحة الاسم المشتركة، وهي مكتبة تشير إلى مكتبة أخرى يتطلب يشير إلى مراجع تلك المكتبة على الرغم من أنها لا تستهلكها.

من الصعب للغاية أن توضح في جملة واحدة، ولكن فيما يلي خطوات لإعادة إنتاج السلوك (إيلاء اهتمام وثيق لاسم المساحات):

قم بإنشاء مكتبة تسمى Library وإضافة فئة واحدة إلى تلك المكتبة:

namespace Ploeh
{
    public abstract class Class1InLibraryA
    {
    }
}

تأكد من أن المكتبة متوافقة مع CLS عن طريق إضافة [assembly: CLSCompliant(true)] إلى femlicsinfo.cs.

قم بإنشاء مكتبة أخرى تسمى LibraryB والمرجعية Library. أضف الفئات التالية إلى LibraryB:

namespace Ploeh.Samples
{
    public class Class1InLibraryB : Class1InLibraryA
    {
    }
}

و

namespace Ploeh.Samples
{
    public abstract class Class2InLibraryB
    {
    }
}

تأكد من أن LibraryB هو أيضا متوافق CLS.

لاحظ أن Class1InlibraryB مستمد من نوع في Library، في حين أن class2inlibraryb لا.

الآن قم بإنشاء مكتبة ثالثة تسمى Libraryc و Reference LibraryB (ولكن ليس Librarya). أضف الفصل التالي:

namespace Ploeh.Samples.LibraryC
{
    public class Class1InLibraryC : Class2InLibraryB
    {
    }
}

هذا لا يزال يترجم. لاحظ أن Class1inlibraryc مستمد من الفصل في Libraryb لا تستخدم أي أنواع من Librara.

لاحظ أيضا أن class1inlibraryc محددة في مساحة الاسم التي تعد جزءا من التسلسل الهرمي مساحة الاسم المحددة في LibraryB.

حتى الآن، لا تتم الإشارة إلى Libraryc إلى Library، وبالتالي لا تستخدم أي أنواع من Library، يجمع الحل.

الآن جعل libraryc cls متوافقة كذلك. فجأة، لم يعد الحل يجمع، مما يتيح لك رسالة الخطأ هذه:

يتم تعريف النوع "ploeh.class1inlibrarya" في التجميع غير المراجع. يجب إضافة مرجع إلى التجميع "Ploeh، الإصدار = 1.0.0.0، الثقافة = محايد، SearchKeyToken = NULL".

يمكنك إنشاء الحل مرة أخرى في إحدى الطرق التالية:

  • إزالة الامتثال CLS من Libraryc
  • إضافة مرجع إلى Library (على الرغم من أنك لست بحاجة إليه)
  • قم بتغيير مساحة الاسم في Libraryc بحيث لا جزء من تسلسل أرمية مساحة الاسم في LibraryB (على سبيل المثال إلى FWAAH.Samples.libraryc)
  • تغيير مساحة اسم Class1inlibraryb (أي واحد ليس المستخدمة من Libracyc) بحيث لا تكمن في تسلسل أرمية مساحة الاسم (على سبيل المثال إلى ploeh.samples.libraryb)

يبدو أن هناك بعض التفاعل الغريب بين مساحة المساحة الهرمية والامتثال CLS.

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

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

المحلول

ألقيت نظرة على الوثائق الرسمية ل CLS (http://msdn.microsoft.com/en-us/netframework/aa569283.aspx.)، لكن رأسي انفجر قبل أن أجد إجابة بسيطة.

لكنني أعتقد أن الأساس هو أن المحول البرمجي، من أجل التحقق من امتثال CLS للمحبيات، يحتاج إلى النظر في تسمية التعارضات المحتملة مع مكتبة.

يجب على المترجم التحقق من جميع "أجزاء نوع يمكن الوصول إليها أو مرئية خارج المجموعة المحددة" (CLS Suit 1).

منذ الفئة العامة Class1inlibraryc يرث Class2InlibraryB، يجب أن تحقق من الامتثال CLS ضد Librarya أيضا، على وجه الخصوص لأن "Ploeh. *" أصبح الآن "في نطاق" CLS القاعدة 5 "يجب أن تكون جميع الأسماء المقدمة في نطاق متوافق مع CLS من نوع".

تغيير اسم مساحة اسم class1inlibraryb أو class1inlibraryc حتى يصبح متميزا أنه يقنع المترجم لا توجد فرصة للنزاع الاسم بعد الآن.

إذا اخترت الخيار (2)، فقم بإضافة المرجع وتجميعها، سترى أن المرجع غير ملحوظ بالفعل في بيانات التجميع التجميع الناتجة، لذلك هذا هو تبعية تجميع / التحقق من الوقت فقط.

نصائح أخرى

تذكر أن CLS هي مجموعة من القواعد التي تنطبق على المجالس التي تم إنشاؤها ومصممة لدعم قابلية التشغيل البيني بين اللغات. بمعنى ما، فإنه يحدد أصغر مجموعة فرعية مشتركة من القواعد التي يجب أن يتبعها نوعها للتأكد من أنها لغة ومنصة ملهية. ينطبق CLS-Impliance أيضا على العناصر التي تعتبر مرئية خارج التجمع المحدد.

النظر في بعض المبادئ التوجيهية يجب أن تتبع قانون متوافق مع CLS:

  • تجنب استخدام الأسماء يستخدم عادة ككلمات رئيسية لغات البرمجة.
  • لا نتوقع أن تكون مستخدمو الإطار قادرين على المؤلف الأنواع المتداخلة.
  • افترض أن تطبيقات أساليب نفس الاسم والتوقيع على واجهات مختلفة مستقلة.

قواعد تحديد الامتثال CLS هي:

  • عندما لا تحمل التجميع نظام صريح.clscompleiantattribute، يجب أن يحمل System.clscompliantattribute (FALSE).
  • بشكل افتراضي، يرث نوع من النوع سمة CLS-Impliance من النوع المرفق (لأنواع متداخلة) أو يكتسب مستوى الامتثال المرفق بجمعتها (لأنواع المستوى الأعلى).
  • بشكل افتراضي، يرث الأعضاء الآخرون (الأساليب، الحقول، الخصائص، والأحداث) على توافق CLS-Typiance لنوعهم.

الآن، فيما يتعلق بالمترجم المعني، (CLS Suit 1) يجب أن تكون قادرا على تطبيق قواعد الامتثال CLS- أي معلومات سيتم تصديرها خارج الجمعية وتعتبر نوعا متوافقا مع CLS إذا كان كل شيء علنا أجزاء يمكن الوصول إليها (تلك الطبقات والواجهات والأساليب والحقول والخصائص والأحداث المتاحة لرمز تنفيذها في مجموعة أخرى)

  • لديك تواقيع تتكون فقط من أنواع متوافقة مع CLS، أو
  • يتم تمييزها على وجه التحديد أنها لا توافق CLS.

من خلال قواعد CTS، فإن النطاق هو ببساطة مجموعة / مجموعة من الأسماء وضمن النطاق قد يشير الاسم إلى كيانات متعددة طالما أنها ذات أنواع مختلفة (الأساليب، الحقول، الأنواع المتداخلة، الخصائص، الأحداث) أو لديك توقيعات مختلفة. يحتوي كيان اسمه على اسمه في نطاق واحد بالضبط من أجل تحديد هذا النطاق ويجب تطبيق اسم اسمه. النطاق مؤهلة الاسم.

نظرا لأن الأنواع المسماة، يتم تجميع أسماء الأنواع أيضا في النطاق. لتحديد نوعه بالكامل، يجب أن يكون اسم النوع مؤهل من النطاق. يتم استبدال الأسماء الأنواع بواسطة الجمعية التي تحتوي على تنفيذ هذا النوع.

بالنسبة إلى النطاقات المتوافقة مع CLS، يجب أن تكون جميع الأسماء مستقلة تماما عن النوع، باستثناء حيث تكون الأسماء متطابقة وحلها عن طريق التحميل الزائد. في حالة أخرى، في حين أن CTS تسمح لنوع واحد لاستخدام نفس الاسم لحقل وطريقة، فإن CLS لا (CLS القاعدة 5).

أخذ هذه الخطوة الواحدة، يجب ألا يتطلب نوع متوافق مع CLS تنفيذ أنواع غير متوافقة مع CLS (CLS Suit 20) ويجب أن يرث أيضا من نوع آخر CLS-شكوى (CLS Suit 23).

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

  • يتم حل جميع المراجع إلى الجمعيات الأخرى تحت سيطرة نطاق التجميع الحالي.
  • من الممكن دائما تحديد نطاق التجميع الذي يتم تنفيذ التنفيذ المعين. جميع الطلبات التي نشأت من هذا النطاق التجميعي يتم حلها بالنسبة لهذا النطاق.

ما كل هذا يعني في النهاية هو أنه من أجل التحقق من الامتثال CLS للنوع، يجب أن يكون التحويل البرمجي قادرا على التحقق من ذلك الكل الأجزاء العامة من هذا النوع هي أيضا متوافقة مع CLS. هذا يعني أنه يجب عليه التأكد من أن الاسم فريد من نوعه في النطاق، وأنه لا يعتمد على أنواع غير متوافقة مع CLS لأجزاء من تنفيذها الخاصة وأنه يرث من أنواع أخرى متوافقة مع CLS أيضا. الطريقة الوحيدة لذلك للقيام بذلك هي فحص جميع التجمعات التي مراجع النوع.

تذكر أن خطوة البناء في Visual Studio هي في الأساس غلاف واجهة المستخدم الرسومية حول تنفيذ MSBUILD، وهو ما هو في نهاية المطاف ليس أكثر من طريقة ملكية لاستدعاء مترجم سطر الأوامر C #. لكي يتحقق المحول البرمجي من الامتثال CLS-Impliance لنوع، يجب أن يكون معروفا وتكون قادرا على العثور على جميع التجميعات التي تكتب المراجع (وليس المشروع). نظرا لأنه يتم استدعاؤه عبر MSBUILD وفي نهاية المطاف Visual Studio، فإن الطريقة الوحيدة ل Visual Studio (MSBUILD) لإبلاغها بتلك التجميعات هي من خلال تضمينها كمراجع.

من الواضح، نظرا لأن المحول البرمجي قادر على معرفة أنه "مفقود" المراجع من أجل التحقق من الامتثال CLS والترجمة بنجاح، كان من الممكن أن يكون لطيفا إذا كان يمكن أن يشمل ببساطة تلك المرجع تلقائيا نيابة عننا. المشكلة هنا في تحديد أي نسخة من الجمعية لتشمل و أين أن الجمعية في نظام الملفات. من خلال إجبار المطور على تقديم هذه المعلومات، يساعد التحويل البرمجي في ضمان أنه يتم إعطاء المعلومات الصحيحة. هذا لديه أيضا تأثير جانبي لضمان نسخ جميع التجمعات المعالين إلى Debug/bin أو Release/bin المجلدات أثناء الإنشاء حتى تكون في الدليل الصحيح عند تشغيل التطبيق بعد تجميعها.

تم إصلاح المشكلة في Roslyn، والتي تتوفر في Visual Studio 14.
اعتبارا من يوليو 2014، يتوفر CTP الحالي هنا.
يرى هذا تقرير الخطأ للتفاصيل.

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