C# تفويض تحت سؤال الغطاء
-
03-10-2019 - |
سؤال
كنت أقوم ببعض الحفر في تباين مندوب بعد قراءة السؤال التالي في ذلك: 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 ؛ // الطريقة السهلة لتعيين مندوب باستخدام التباين ، يضيف طبقة من عدم التوجيه رغم ذلك
يمكن لأحد أن يقول لي:
- كيف يمكن استدعاء استدعاء دون تمرير المعلمة المطلوبة بواسطة الوظيفة الثابتة.
- عندما يحدث تحت الغطاء عند تعيين قيمة الإرجاع من الاتصال
- ماذا يعني باري من خلال عدم التوجيه الإضافي (في تعليقه)
المحلول
إنه لا يتصل 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
وسوف يجمع ، لكن هذا لن يوضح هذه النقطة.