سؤال

كنت أقوم ببعض الحفر في تباين مندوب بعد قراءة السؤال التالي في ذلك: Depegate.CreatedElegate () و generics: خطأ في ربط الطريقة المستهدفة

لقد وجدت القليل جدًا من الكود من باري كيلي فيhttps://www.blogger.com/comment.g؟blogid=8184237816669520763&postid=210970853230166434

هنا (في شكل suged-up :-)

using System;

namespace ConsoleApplication4
{
    internal class Base
    {
    }

    internal class Derived : Base
    {
    }

    internal delegate void baseClassDelegate(Base b);

    internal delegate void derivedClassDelegate(Derived d);


    internal class App
    {
        private static void Foo1(Base b)
        {
            Console.WriteLine("Foo 1");
        }

        private static void Foo2(Derived b)
        {
            Console.WriteLine("Foo 2");
        }

        private static T CastDelegate<T>(Delegate src)
            where T : class
        {
            return (T) (object) Delegate.CreateDelegate(
                                    typeof (T),
                                    src.Target,
                                    src.Method,
                                    true); // throw on fail
        }

        private static void Main()
        {
            baseClassDelegate a = Foo1; // works fine

            derivedClassDelegate b = Foo2; // works fine

            b = a.Invoke; // the easy way to assign delegate using variance, adds layer of indirection though

            b(new Derived());

            b = CastDelegate<derivedClassDelegate>(a); // the hard way, avoids indirection

            b(new Derived());
        }
    }
}

أنا أفهم كل ذلك باستثناء هذا الخط (ما يبدو بسيطًا جدًا).

ب = A.Invoke ؛ // الطريقة السهلة لتعيين مندوب باستخدام التباين ، يضيف طبقة من عدم التوجيه رغم ذلك

يمكن لأحد أن يقول لي:

  1. كيف يمكن استدعاء استدعاء دون تمرير المعلمة المطلوبة بواسطة الوظيفة الثابتة.
  2. عندما يحدث تحت الغطاء عند تعيين قيمة الإرجاع من الاتصال
  3. ماذا يعني باري من خلال عدم التوجيه الإضافي (في تعليقه)
هل كانت مفيدة؟

المحلول

إنه لا يتصل Invoke (لاحظ عدم وجود ()) ، يستخدم إنشاء مندوب ضمني لتعيين b يساوي جديد derivedClassDelegate مثال يشير إلى Invoke طريقة a. عدم التوجيه الإضافي هو أنه عندما b يتم استدعاؤه ، ويدعو a.Invoke(new Derived()) افضل من مجرد a(new Derived()).

لجعل ما يحدث بالفعل أكثر وضوحا:

baseClassDelegate a = Foo1; // works fine 

derivedClassDelegate b = Foo2; // works fine 

b = new derivedClassDelegate(a.Invoke); // the easy way to assign delegate using variance, adds layer of indirection though 

b(new Derived());

b = CastDelegate<derivedClassDelegate>(a); // the hard way, avoids indirection 

b(new Derived());

أول مكالمة إلى b النتائج في سلسلة مثل هذه (المعلمات القضاء على البساطة):

b() -> a.Invoke() -> Foo1()

الدعوة الثانية إلى b النتائج في هذا:

b() -> Foo1()

لكن

هناك حاجة إلى هذا فقط إذا كنت بحاجة إلى مندوب من توقيع واحد لاستدعاء مندوب لتوقيع آخر (أقل تقييدًا). في مثاله ، يمكنك فقط تعيين b = Foo1 وسوف يجمع ، لكن هذا لن يوضح هذه النقطة.

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