How delegates work (in the background)?

前端 未结 6 555
温柔的废话
温柔的废话 2020-12-10 06:16

How do delegates work in c# behind the scenes and how can they be used efficiently?

EDIT: I know how they work on the surface(they are basically function pointers a

相关标签:
6条回答
  • 2020-12-10 06:41

    Re efficiency - it isn't clear what you mean, but they can be used to achieve efficiency, by avoiding expensive reflection. For example, by using Delegate.CreateDelegate to create a (typed) pre-checked delegate to a dynamic/looked-up method, rather than using the (slower) MethodInfo.Invoke.

    For a trivial example (accessing the static T Parse(string) pattern for a type), see below. Note that it only uses reflection once (per type), rather than lots of times. This should out-perform either reflection or typical TypeConverter usage:

    using System;
    using System.Reflection;
    static class Program { // formatted for space
        static void Main() {
            // do this in a loop to see benefit...
            int i = Test<int>.Parse("123");
            float f = Test<float>.Parse("123.45");
        }
    }
    static class Test<T> {
        public static T Parse(string text) { return parse(text); }
        static readonly Func<string, T> parse;
        static Test() {
            try {
                MethodInfo method = typeof(T).GetMethod("Parse",
                    BindingFlags.Public | BindingFlags.Static,
                    null, new Type[] { typeof(string) }, null);
                parse = (Func<string, T>) Delegate.CreateDelegate(
                    typeof(Func<string, T>), method);
            } catch (Exception ex) {
                string msg = ex.Message;
                parse = delegate { throw new NotSupportedException(msg); };
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-10 06:45

    When you define your delegate

    internal delegate void Feedback(Int32 value);
    

    the compiler actually defines a complete class that looks something like this:

    internal class Feedback : System.MulticastDelegate {  
       // Constructor  
       public Feedback(Object object, IntPtr method);  
    
       // Method with same prototype as specified by the source code  
       public virtual void Invoke(Int32 value);  
    
       // Methods allowing the callback to be called asynchronously  
       public virtual IAsyncResult BeginInvoke(Int32 value,  AsyncCallback callback, Object object);  
    
       public virtual void EndInvoke(IAsyncResult result);  
    }
    

    Source: Jeffrey Richter - CLR via C#, chapter 17

    0 讨论(0)
  • 2020-12-10 06:47

    C# compiler generates a full blown class when you create a delegate. This class holds a list of function references, as Konrad mentioned. The nice thing about delegates is that they provide you with easy way to execute the task asynchronously with notification callback. What this means is that you can be notified when your background operation completes. Threadpool doesn't provide this feature. Delegates are a vast topic and I find Jeff Richter's (CLR via C#) and Albahari (C#3) books of particular help.

    0 讨论(0)
  • 2020-12-10 06:56

    The first part of the question is relatively easy: delegates store a list of function pointers. If you invoke a delegate, it calls all the function pointers in that internal list. Adding and removing a receiver (via Delegate.Combine and Delegate.Remove) amounts to adding to and removing from that list.

    For more low-level information, refer to ECMA-335 (the CLI standard), section II.14.5 (Method pointers) and II.14.6 (Delegates). In particular, note that a delegate consists of an instance pointer (of type System.Object) and a method pointer (of type System.IntPtr). A method pointer can be obtained (in CIL) via the ldftn or ldvirtftn (for virtual function calls) instructions.

    These two pieces of information identify any method.

    how can they be used efficiently?

    What do you mean by that? Do you know about events or is your question more specialized?

    0 讨论(0)
  • 2020-12-10 07:02

    Delegates in C# are lists of method pointers. I.e. they store references to code, and you can invoke the methods via the pointers. This is useful in many cases. The common example is for event handlers where delegates are used to implement a publisher/subscriber pattern.

    0 讨论(0)
  • 2020-12-10 07:04

    C# delegates are objects (check the System.Delegate class) that encapsulate a reference to an object and a method pointer. They can also have a null reference to object to represent a call to a static method.

    When invoking the delegate with arguments, the delegate crafts a call to the referenced method on referenced object with specified arguments.

    A compiled delegate Invoke method is directly handled by the runtime (as visible with Reflector):

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

    The runtime use all the info internaly to compile a standard method call to the referenced method.

    0 讨论(0)
提交回复
热议问题