Reflection and delegates

  1. When do we need to use reflection?
  2. How to create delegates dynamically?
  3. How to invoke delegates dynamically?

In case we don’t have information about delegates and methods we can create delegates and bind them with methods dynamically.

The CLR has special method that creates a delegate of the specified type that represents the specified static or instance method, with the specified first argument and the specified behavior on failure to bind.

Delegate.CreateDelegate Method (Type, Object, MethodInfo, Boolean)

Parameters

type

Type: System..::.Type
A
Type representing the type of delegate to create.

firstArgument

Type: System..::.Object
An
Object that is the first argument of the method the delegate represents. For instance methods, it must be compatible with the instance type. A null reference for static methods.

method

Type: System.Reflection..::.MethodInfo
The
MethodInfo describing the static or instance method the delegate is to represent.

throwOnBindFailure

Type: System..::.Boolean
true to throw an exception if method cannot be bound; otherwise, false.

Return Value

Type: System..::.Delegate
A delegate of the specified type that represents the specified static or instance method, or nullNothingnullptra null reference (Nothing in Visual Basic) if throwOnBindFailure is false and the delegate cannot be bound to method.

The CLR has special methods to invoke (late-bound) the method represented by the current delegate dynamically.

Delegate.DynamicInvoke

Parameters

args

Type: array<System..::.Object>[]()[]
An array of objects that are the arguments to pass to the method represented by the current delegate.
-or-
nullNothingnullptra null reference (Nothing in Visual Basic), if the method represented by the current delegate does not require arguments.

Return Value

Type: System..::.Object
The object returned by the method represented by the delegate.

Example 1:

namespace UsefullMyCallbackMethods

{

    internal delegate int TwoIntParamsDelegate(int a, int b);

 

    public class MethodsCollection

    {

        public static int Minus(int a, int b)

        {

            return a – b;

        }

 

        private int Sum(int a, int b)

        {

            return a + b;

        }

    }

}

 

namespace Reflection

{

    class Program

    {

        static void Main(string[] args)

        {

            string path = @"C:UsefullMyCallbackMethods.dll";

 

            Assembly asm = Assembly.LoadFile(path);

            Type classType = asm.GetType("UsefullMyCallbackMethods.MethodsCollection");

            Type delType = asm.GetType("UsefullMyCallbackMethods.TwoIntParamsDelegate");

 

            Delegate instanceDelegate = GetInstanceMethodDelegate(asm, classType, delType);

            Delegate staticDelegate = GetStaticMethodDelegate(asm, classType, delType);           

 

            object[] param = new object[] { 5, 3 };

 

            //Dynamic invocation with given parameters.

            Trace.WriteLine(instanceDelegate.DynamicInvoke(param));

            Trace.WriteLine(staticDelegate.DynamicInvoke(param));

 

            Console.ReadKey();

        }

 

        /// <summary>

        /// Gets a created delegate of the specified type that represents the specified instance method.

        /// </summary>

        /// <param name="asm">The assembly which contains the type which is bound to the instance method</param>

        /// <param name="classType">The Type which contains the getting method</param>

        /// <param name="delType">The Type of delegate to create.</param>

        /// <returns>A delegate of the given type that represents the specified instance method</returns>

        private static Delegate GetInstanceMethodDelegate(Assembly asm, Type classType, Type delType)

        {

            //The MethodInfo describing instance method the delegate is to represent.

            MethodInfo sumMethodInfo = classType.GetMethod("Sum", BindingFlags.Instance | BindingFlags.NonPublic);

 

            //The object to which the delegate is bound

            Object target = asm.CreateInstance("UsefullMyCallbackMethods.MethodsCollection");

 

            Delegate createdDelegate = null;

 

            try

            {

                createdDelegate = Delegate.CreateDelegate(delType, target, sumMethodInfo, true);

            }

            catch (ArgumentException exception)

            {

                Trace.Write(exception.ToString());

            }

 

 

            return createdDelegate;

        }

 

        /// <summary>

        ///  Gets a created delegate of the specified type that represents the specified static method.

        /// </summary>

        /// <param name="asm">he assembly which contains the type which is bound to the static method</param>

        /// <param name="classType">The Type which contains the getting method</param>

        /// <param name="delType">The Type of delegate to create.</param>

        /// <returns>A delegate of the given type that represents the specified static method</returns>

        private static Delegate GetStaticMethodDelegate(Assembly asm, Type classType, Type delType)

        {

 

            MethodInfo minusMethodInfo = classType.GetMethod("Minus", BindingFlags.Static | BindingFlags.Public);

 

            Delegate createdDelegate = null;

 

            try

            {

                //For static methods we don’t need to pass object’s instance where the static methods are defined 

                createdDelegate = Delegate.CreateDelegate(delType, null, minusMethodInfo, true);

            }

            catch (ArgumentException exception)

            {

                Trace.Write(exception.ToString());

            }

 

 

            return createdDelegate;

        }

 

    }

}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s