委托的额外优势是什么 [英] What is the Extra Advantage of Delegate

查看:75
本文介绍了委托的额外优势是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,我在网站代码项目中阅读了一篇有关委托的文章
我认为那是被枪杀了,同时我也从中得到了基本的认识
我有一个愚蠢的疑问,请告诉我:confused:


在编码的同时,我可以调用任何这样的方法
例如:

Recently I have read one article in website code project regarding delegate
I appriciate that it was shot and simlpe I got basic idea out of that
I have a silly doubt please clear me:confused:


While I do coding I can call any method like this
eg :

obj1.Metho1();
obj1.Method();

根据说明,我知道我们像这样调用函数

例如:

As per the explanation I understood that we call the function like this

eg:

Delegate_Multicast func = new Delegate_Multicast(Method1);
func += new Delegate_Multicast(Method2);
func(1,2);             // Method1 and Method2 are called
func -= new Delegate_Multicast(Method1);
func(2,3);

根据我的理解,两种方式都可以提供相同的结果和相同的编码效果.

如果我想执行Method1和Method2,则必须将这些方法分别附加到委托上

所以我不明白我们可以从哪里获得使用委托功能而不是进入旧方法调用的优势.有人可以解释一下X |

As per my understanding both ways are giving same result and same effort of coding.

If I want to execute Method1 and Method2 I have to attach these methods seperatly to the delegate

so I dont understand where we can get the advantage of using delegate featue rather than going into old style of method calling. can anyone please explain X|

推荐答案

好吧,如果您尝试创建在问题中出现的人为简化的用例,则没有机会看到额外优势"吧?

我宁愿不是在谈论优势",而是在谈论主要技术特征.代表有什么特别之处;没有它们,我们将无法实现什么有用的效果?

让我们退后一步,考虑一下委派的最简单,最基本的方面,因为如果您了解委派,则可以派生所有高级用法.我们应该解决使用惯常方法无法获得的某些利润的情况. (我不会涉及多播功能,因为它甚至无关紧要.)

首先,让我们仅将代表"一词用于代表类型,代表类型的实例称为代表实例",而不是将它们混合使用.首先,重要的是要理解,委托实例是方法参数的变量.也就是说,委托实例被视为一等公民"对象.同时,委托实例代表某种方法(无论是否匿名),以此方式,方法可以被视为一等公民"对象.

现在,是时候考虑委托实例的解剖了.出于当前的目的,我们可以将委托实例视为两个基本部分的数据结构:对代码入口点的引用和对类中某些对象的引用.对于静态方法,对object的引用可以为null.换句话说,我们有一个类C,方法C.MC.S(让第二个静态),以及一个此类cinst的实例:

Well, if you try to create artificially simplified use cases as you present in your Question, you don''t have a chance to see "Extra Advantage", right?

I would prefer talking not about "advantage", but about a principal technological feature. What''s so special about delegates; what is the useful effect which we cannot achieve without them?

Let''s step back and consider the simplest and most fundamental aspect of delegation, because if you understand it, you can derive all advanced uses. We should come to the case where we get some profit not achievable using customary methods. (I''m not going to touch multicast feature, because it is even irrelevant.)

First of all, let''s use the word "delegate" only for a delegate type, and the instances of a delegate types call "delegate instance", not mixing them. First, it is important to understand, that a delegate instance is a variable of a method parameter. That said, delegate instances are considered as "first-class citizens" objects. At the same time, a delegate instance represents some method (anonymous or not), in this way, methods can be considered as "first-class citizens" objects.

Now, this is the time to consider anatomy of a delegate instance. For our current purpose, we can consider a delegate instance as a data structure of two essential parts: a reference to the code entry point and a reference to some object of the class. The reference to object can be null, for static methods. In other words, we have a class C, the method C.M, C.S (let''s make a second one static) and an instance of this class cinst:

class C {
    public delegate void DeletateType(/*...*/);
    //return types can be different; I use void for simplicity
    internal void M(/*...*/) {/*...*/};
    internal static void S(/*...*/) {/*...*/}
}
//...
C cinst = new C(/*...*/);



基于此,我们可以有两个委托实例:[C.M, cinst][C.S, null],重要的是,cinst是与该方法相同的类的实例. (也有对委托类型元数据的引用,让我们暂时忘记它.)

如您所知,每个实例方法都被称为具有附加参数this(静态方法中不存在),该参数用于携带对该实例的引用.根据我的伪代码[C.M, cinst]中的数据结构,我们可以调用方法的所有内容:我们在入口点C.M调用,并使用this=cinst作为第一个参数,根据委托类型.

现在,让我们记住委托实例是一个变量,可以作为方法参数传递.因此,我们可以使用C.DelegateType作为附加的抽象级别来创建完全不相关的类:



Based on that, we can have two delegate instances: [C.M, cinst] and [C.S, null], importantly, cinst is the instance of the same class as the method. (There is also a reference to delegate type meta-data, let''s forget it for a while.)

As you should understand, every instance method is called having additional parameter this (absent in static methods) used to carry a reference to the instance. Having a data structure like in my pseudo-code [C.M, cinst], we have everything to call a method: we call at the entry point C.M and use this=cinst as a first parameter, other parameters are passes explicitly, according to the delegate type.

Now, let''s remember the delegate instance is a variable and can be passed as a method parameter. So, we can have completely unrelated class using C.DelegateType as an additional level of abstraction:

class DelegateUser {
    internal void CompositeAction(
         int data,
         C.DelegateType injectedAction,
         /*some type(s)*/ injectedActionParameter) {
        //do something with first parameter: data
        //call action from second parameter:
        if (injectedAction != null)
            //instance of C (for example) passed as hidden parameter:
            injectedAction(injectedActionParameter); 
    } //CompositeAction
} //DelegateUser

//...

//In this way, we can call CompositeAction with different instances (apparently)
//of different methods (aha! -- of matching profile, of course)
//of different classes (important and not trivial!):

DelegateUser user = new DelegateUser( //...
user.C CompositeAction(3, new C(/*...*/).M(4, /*...*/);
//Profit: can use different class, other then C, different methods, etc. 



这可以被视为经典" OOP之上的另一种灵活性.当然,如果我们将injectedAction设为虚拟函数,则可以调用不同版本的injectedAction,因此通过 late绑定它会有所不同,但是它应该是来自同一类层次结构的类的方法.委托更多是临时的,但方法更灵活.

这种行为有很多用途.最基本的方法是传递一个委托,以为任意复杂的方法(例如遍历某些数据)提供任意的谓词方法:



This can be considered as a different flexibility on top of "classical" OOP. Of cource we could call different versions of injectedAction if we make it a virtual function, so it will be different through late binding, but it should be a method of a class from the same class hierarchy. The delegate is more of ad-hoc, but more flexible method.

There are a lot of uses of this behefit. Most basic is passing a delegate to provide an arbitrary predicate method to some complex method, for example, traversing some data:

void TraverseData(
         MyDataContainer data,
         Func<DataElement> predicate,
         Action<DataElement> dataProcessor) {
    //...
    DateElement element = //...
    if (predicate(element))
        dataProcessor(element);
    //...
} //TraverseData



假设有两种不同的数据遍历算法,两个不同的谓词和两个不同的数据处理器,而没有代表将所有8种情况组合在一起,则必须写下8种不同的TraverseData版本,从而失去所有可能的代码重用.这就是为什么将方法作为一流公民(以委托实例的形式)如此重要的原因.

有关另一个有趣的示例,请参阅技巧/窍门"部分中的小文章:
在调用内部隐藏临时方法方法的主体 [ ^ ].

另请参阅关于this角色的其他答案:静态函数 [ ^ ].它与委托无关,但提供了一些实例与静态方法的说明.

进一步阅读可能需要了解关闭: http://en.wikipedia.org/wiki/Closure_(computer_science) [ ^ ]和然后是 lambda表达式(在.NET中可以理解): http://en.wikipedia.org/wiki /Functional_programming [^ ].


有关委托的高级用法,请参阅我最近的文章:动态方法调度器 [用于线程通信的简单阻塞队列和线程间调用 [ ^ ].

—SA



Having, let''s say two different algorithm for data traversal, two different predicates and two different data processors, without delegates to combine all 8 cases would have to write down 8 different versions of TraverseData, loosing all possible code reuse. That''s why treating methods as first-class citizens (in the form of delegate instances) is so important.

For another interesting example, see my small article in Tips/Tricks section:
Hide Ad-hoc Methods Inside the Calling Method’s Body[^].

See also my other answer on the role of this: static functions[^]. It has nothing to do with delegates but provides some clarification on instance vs. static methods.

Further reading should probably needs understanding Closures: http://en.wikipedia.org/wiki/Closure_(computer_science)[^] and then lambda expressions, as they are understood in .NET: http://en.wikipedia.org/wiki/Functional_programming[^].


For advanced use of delegates see my recent article: Dynamic Method Dispatcher[^]

and a short Tips/Trick article: Simple Blocking Queue for Thread Communication and Inter-thread Invocation[^].

—SA


我想补充一点.

如果要使用LoadLibrary()/GetProcAddress()使用.dll文件的方法,则可以使用委托.

这是将C#代码连接到C ++代码的方法之一.
One more point I want to add.

If you want to use LoadLibrary()/GetProcAddress() to use methods of .dll files you have use delegates.

It''s one of the ways to connect C# codes to C++ codes.


在第一种情况下,您正在编写无法在运行时更改的代码.

使用委托,您可以决定在运行时调用哪种方法.
因此,委托是实现后期绑定的一种方法.
In the first case, you are writing code which cannot change at runtime.

With delegates, you can decide which method to call at runtime.
Thus delegates are one way to achieve late binding.


这篇关于委托的额外优势是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆