سؤال

أثناء فحص المندوبين في C # و .net بشكل عام، لاحظت بعض الحقائق المثيرة للاهتمام:

إنشاء مندوب في C # يخلق فئة مستمدة من MulticastDelegate مع منشئ:

.method public hidebysig specialname rtspecialname instance 
   void .ctor(object 'object', native int 'method') runtime managed { }

وهذا يعني أنه يتوقع المثيل ومؤشر إلى الطريقة. ومع ذلك، فإن بناء جملة بناء مندوب في ج # يقترح أنه يحتوي على منشئ

new MyDelegate(int () target)

حيث يمكنني التعرف int () كحل وظيفة (int *target() سيكون مؤشر وظيفة في C ++). من الواضح أن برنامج التحويل البرمجي C # يختار الطريقة الصحيحة من مجموعة الأسلوب المحددة بواسطة اسم الوظيفة وتبني المفوض. لذا فإن السؤال الأول سيكون، أين يكون برنامج التحويل البرمجي C # (أو Visual Studio، أن يكون دقيقا) هذا التوقيع المنشئ من؟ لم ألاحظ أي سمات خاصة أو شيء من شأنه أن يكون تمييزا. هل هذا نوع من مترجم / VisualStudio Magic؟ إذا لم يكن كذلك، هو T (args) target البناء صالح في C #؟ لم أتمكن من الحصول على أي شيء مع تجميعه، على سبيل المثال:

ANT () الهدف = mymethod؛

غير صالح، لذلك يفعل أي شيء مع MyMetod, ، على سبيل المثال دعوة .ToString() على ذلك (حسنا هذا لا معنى له، لأن هذه هي الطريقة من الناحية الفنية مجموعة, ، لكنني أتصور أنه ينبغي أن يكون من الممكن اختيار طريقة من خلال الصب، على سبيل المثال (int())MyFunction. وبعد فهل هذا من هذا المترجم بحت النظر في البناء من خلال العاكس يكشف بناء جملة آخر:

Func CS $ 1 $ 0000 = New Func (NULL، (INTPTR) FOO)؛

هذا متسق مع توقيع منشئ التفكيك، ومع ذلك لا يجمع هذا!

ملاحظة واحدة مثيرة للاهتمام هي أن الفصول Delegate و MulticastDelegate لديك مجموعات أخرى من المنشئين:

. method family hidebysig specialname rtspecialname مثيل الفراغ .ctor (فئة system.type الهدف، طريقة السلسلة ") cil إدارة

أين يحدث الانتقال من مثيل ومؤشر الأسلوب إلى نوع واسم طريقة السلسلة؟ يمكن أن يفسر هذا من قبل runtime managed الكلمات الرئيسية في توقيع منشئ المندوب مخصص، أي هل يدق وقت التشغيل القيام به هنا؟

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

كنت أتساءل عما إذا كان هذا التأكيد صحيحا، وما إذا كان بناء جملة مثيل الوظيفة يحتوي على بعض المعنى الأعمق في C # أو هو مجرد بعض التنسيق المستمر المنفذ بواسطة الجزء السحري Visual Studio من أجل الوضوح (مما يجعل الشعور، لأنه يبدو وكأنه C غير صالح C #)؟ باختصار، إذا كنت تنفذ Intisisense، هل يجب علي القيام ببعض السحر للمندوبين أو بإمكاني بناء اقتراح بعض آلية ذكية؟

التحرير النهائي: إذن، الإجماع الشهير هو أن هذا هو في الواقع مقابل السحر. رؤية أمثلة أخرى (راجع تعليق MARC Gravell's) من هذا السلوك مقابل VS يقنعني أن هذا هو الحال.

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

المحلول

يتم حل الوسيطة الأولى من مرجع الكائن (أو null الأساليب الثابتة)؛ لا سحر هناك.

إعادة ثانيا حجة، ومع ذلك - إنه مؤشر غير مدار (INTER)؛ باختصار، لا يوجد بديل مباشرة بناء الجملة C # الذي يمكنه استخدام هذا المنشئ - يستخدم تعليمات IL الخاصة (ldftn) لحل وظيفة البيانات الوصفية. ومع ذلك، يمكنك استخدام Delegate.CreateDelegate لإنشاء المندوبين عبر التفكير. يمكنك أيضا استخدام IL Emit (DynamicMethod إلخ)، لكنها ليست ممتعة.

نصائح أخرى

تحدد أول مندوب (هذه هي الطريقة التي يعرفها Visual Studio توقيع الطريقة المستهدفة):

delegate void MyDelegate();

ثم تقوم ببناء مثيلات المندوبين مثل هذا:

MyDelegate method = new MyDelegate({method name});

// If this was the method you wanted to invoke:
void MethodToInvoke()
{
    // do something
}

MyDelegate method = new MyDelegate(MethodToInvoke);

يختار C # تلقائيا الطريقة التي تطابق توقيع المندوب.

تحرير: عندما يظهر لك Intellisense Visual Studio int () target اقتراح، إنه يظهر لك توقيع أساليب C # التي يمكنك استخدامها. يترجم المترجم C # تمثيل C # ل IL. سيبدو تنفيذ IL مختلفا، لأن IL ليس لغة أسلوب C، ويوفر برنامج التحويل البرمجي C السكر النحوي إلى مجردة تفاصيل التنفيذ.

هذا مجرد تخمين، لذلك لا تطلق النار علي إذا كنت مخطئا، لكنني أعتقد أن Intellisense هو الحصول على توقيع الأسلوب المستهدفة من Invoke الطريقة المعرفة على المندوب. العاكس يظهر بوضوح أن Invoke طريقة بشأن System.Action<T> هو:

[MethodImpl(0, MethodCodeType=MethodCodeType.Runtime)]
public virtual void Invoke(T obj);

وهو نفس اقتراح التوقيع الذي يقدمه Intellisense. السحر هو التحسس الذكي، عند اكتشاف نوع المندوب، ينظر إلى Invoke الطريقة وتقترح منشئ يأخذ هدفا يطابقه.

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