creating generic object or generic method with reflection.

Some times i am in a situation that i needed to create a generic Type or a generic Method with a changing type at runtime. I will start with the generation of a generic method. Lets asume i have a method ConvertValue defined in a class Converter:

public class Converter
{
    public TResult ConvertValue<TResult>(int value)
    {            
        TResult resultValue = (TResult)Convert.ChangeType(value, typeof(TResult));
        return resultValue;         
    }
}
var intValue = 10;
Converter converter = new Converter();
double doubleValue = converter.ConvertValue(intValue);

As we see that method converts an int value to a generic type, in our case in a double. But what is if we dont know the type we want to convert in the intValue at compile type. What if the type is choosen at runtime. Then we need the MakeGenericMethod method from the System.Reflection namespace. That call builds a generic method and then we can invoke that method with the correct generic type.

public class CreateGenericTypeAndMethod
{
    public static object MakeGenericMethod(object obj, string methodName, 
                                           Type innerType, params object[] args)
    {            
        MethodInfo method = obj.GetType().GetMethod(methodName, 
            BindingFlags.Public | BindingFlags.NonPublic |
            BindingFlags.Instance | BindingFlags.Static);
        MethodInfo generic = method.MakeGenericMethod(innerType);
        return generic.Invoke(obj, args);
    }
}
var intValue = 10;
Type type = typeof(double);
object obj = MakeGenericMethod(new Converter(), "ConvertValue", type, 10);
// obj is now from type double and has the value 10.0
var str = String.Format("{0:0.0}",((double)obj));
Console.WriteLine("obj has the type {0} and the value {1}", obj.GetType(), str);

After the MakeGenericMethod call the obj object is now from type double and has the value 10.0 .
objAsDouble
But what is if you want to generate a class with a generic type T. In the next example i show how to generate a Stack of type T. The type T is not known at compile type but at runtime.

public class Stack<T>
{
    private List<T> list = new List<T>();

    public void Push(T value)
    {
        list.Add(value);
    }

    public T Pop()
    {
        if (list.Count > 0)
        {
            T value = list[list.Count - 1];
            list.RemoveAt(list.Count - 1);
            return value;
        }
        return default(T);
    }
}
public class CreateGenericTypeAndMethod
{
    public static object MakeGenericType(Type generic, Type innerType, 
        params object[] args)
    {
        Type specificType = generic.MakeGenericType(new Type[] { innerType });
        return Activator.CreateInstance(specificType, args);
    }
}
Type type = typeof(double);
object stack = CreateGenericTypeAndMethod.MakeGenericType
    (typeof(Stack<>), type, new object[] { });

Here i generate a Stack for double values.

stackAsDouble

I call the MakeGenericType method with the type of the object (Stack) and the type of the generic type (double). In the MakeGenericType method i generate the generic type of the Stack (Stack). For that generation i use the MakeGenericType method of the Type class. With that type i instanciate the object by calling Activator.CreateInstance. That is all i have to do to create the Stack.

Here is the complete implementation of the CreateGenericTypeAndMethod class. There are two overloads for generic type generation and generic methode generation with one generic parameter or multible generic parameters.


public class CreateGenericTypeAndMethod
{
    public static object MakeGenericType(Type generic, Type innerType, 
        params object[] args)
    {
        Type specificType = generic.MakeGenericType(new Type[] { innerType });
        return Activator.CreateInstance(specificType, args);
    }

    public static object MakeGenericType(Type generic, Type[] innerTypes, 
        params object[] args)
    {
        Type specificType = generic.MakeGenericType(innerTypes);
        return Activator.CreateInstance(specificType, args);
    }

    public static object MakeGenericMethod(object obj, string methodName, 
        Type innerType, params object[] args)
    {            
        MethodInfo method = obj.GetType().GetMethod(methodName, 
            BindingFlags.Public | BindingFlags.NonPublic | 
            BindingFlags.Instance | BindingFlags.Static);
        MethodInfo generic = method.MakeGenericMethod(innerType);
        return generic.Invoke(obj, args);
    }

    public static object MakeGenericMethod(object obj, string methodName, 
        Type[] innerTypes, params object[] args)
    {
        MethodInfo method = obj.GetType().GetMethod(methodName, 
            BindingFlags.Public | BindingFlags.NonPublic | 
            BindingFlags.Instance | BindingFlags.Static);
        MethodInfo generic = method.MakeGenericMethod(innerTypes);
        return generic.Invoke(obj, args);
    }
}
Advertisements

dynamic dispatch in c#

In this post i want to write about dynamic dispatch. So dynamic dispatch is used for code invocation and describes if a language uses compile time information or run time information to invoke a method. The two main concepts with dynamic dispatch are single dispatch and multible dispatch. I wanted to start with the simpler one and most common in object orientated languages, with single dispatch.

  • Single dispatch in c# is polymorphistic overriding of methods. The following example shows the c# code for overriding.
    public class Animal
    {       
        public virtual void VirtualShout()
        {
            Console.WriteLine("Animal virtual shouts");
        }
        public void Shout()
        {
            Console.WriteLine("Animal shouts");
        }
    }
    
    public class Cat : Animal
    {        
        public new void Shout()
        {
            Console.WriteLine("Cat shouts");
        }
    }
    
    public class SingleDispatch
    {
        public void Dispatch()
        {
            Animal animal = new Cat();
            animal.VirtualShout();
            animal.Shout();
        }
    }

    Single dispatch is normally implemented with virtual tables. That means the compiler produces a table with entries depending on the methods of the classes. In the Animal example the virtual table for the Animal and the Cat class looks the following way.

       
   Animal:
   vtableAnimal 

   Cat:
   vtableCat

Here we see the output of the single dispatch example:
SingleDispatchOutput
As we see if we call animal.VirtualShout() the decision which VirtualShout method is called (Animal or Cats one) is made at runtime. When the call gets executed the runtime looks at the virtual table and calls the method that stands in that virtual table. In our case the VirtualShout method of the Animal class is called because it is not ovverriden in the Cat class. In c# that mechanismus works only for virtual methodes (in java every method is automatic virtual). The Shout() method is not virtual and so the decision which method to call is choosen at compile time and does not change at runtime. The importand point why this virtual call mechanismus is called single dispatch is because the decision which method to call is made by the single object (If it is a Animal object it has a pointer to the Animal virtual table if it is a Cat it has a pointer to the Cat virtual table).

  • multible dispatch works with the dynamic keyword in c# the following example shows multible dispatch
    public class Owner
    {
        public virtual string Name
        {
            get { return "Owner"; }
        }
    }
    
    public class Mathias : Owner
    {
        public override string Name
        {
            get { return "Mathias"; }
        }
    }
    
    public class Animal
    {       
        public virtual void Shout(Owner owner)
        {
            Console.WriteLine("Animal Shouts to Owner object {0}", owner.Name);
        }
    
        public virtual void Shout(Mathias mathias)
        {
            Console.WriteLine("Animal Shouts to Mathias object {0}", mathias.Name);
        }
    }
    
    public class Cat : Animal
    {        
        public override void Shout(Owner owner)
        {
            Console.WriteLine("Cat Shouts to Owner object {0}", owner.Name);
        }
    
        public override void Shout(Mathias mathias)
        {
            Console.WriteLine("Cat Shouts to Mathias object {0}", mathias.Name);
        }
    }   
    
    public class MultibleDispatch
    {
        public void Dispatch()
        {
            Animal animal = new Animal();
            Owner owner = new Mathias();
            animal.Shout(owner);
            dynamic dynamicOwner = new Mathias();
            animal.Shout(dynamicOwner);
        }
    }

    Multible dispatch means that the decision which method should be called is made by the type of all the methodes parameter. In c# that decision is normally met at compile time, that means the compiler looks at the parameter types of the methodes and chooses the method that fits best. In the example we have two classes Owner and Mathias. Mathias is derifed from Owner. If we declare an Owner and make it an instance of Mathias, and call the Shout(owner) method the binding is made at compile time. That means the Shout method with the first method (Shout(Owner owner)) is called because the compiler uses the type of owner (for the compiler that type is Owner) to call the method. So that call is single dispatch because it uses only the instance objects type Animal to decide which method to call. If we want a call that recognises the correct type of the parameter (the type is Mathias not Owner) we have to move the decision which method to call to runtime. We do that with the dynamic keyword. If we build a dynamic object dynamicOwner that object is from type object and if the runtime makes the Shout(dynamicOwner) call it knows what type dynamicOwner really is (Mathias) and it chooses the correct method (Shout(Mathias mathias)). Here is the output of the Dispatch() method.
    MultibleDispatchOutput
    So now the decision is made by the parameter type and if we have more than one parameter, the decision is made by all the parameter types as we see in the following example.

    public class Animal
    {  
        public virtual void ShoutTwoOwners(Owner ownerOne, Owner ownerTwo)
        {
            Console.WriteLine(
                "Animal Shouts to Owner one object with name {0}, Owner two object with name {1}",
                ownerOne.Name, ownerTwo.Name);        
        }
    
        public virtual void ShoutTwoOwners(Owner ownerOne, Mathias mathiasTwo)
        {
            Console.WriteLine(
                "Animal Shouts to Owner one object with name {0} Mathias two object with name {1}",
                ownerOne.Name, mathiasTwo.Name);
        }
    
        public virtual void ShoutTwoOwners(Mathias mathiasOne, Owner ownerTwo)
        {
            Console.WriteLine(
                "Animal Shouts to Mathias one object with name {0} Owner two object with name {1}", 
                mathiasOne.Name, ownerTwo.Name);        
        }
    
        public virtual void ShoutTwoOwners(Mathias mathiasOne, Mathias mathiasTwo)
        {
            Console.WriteLine(
                "Animal Shouts to Mathias one object with name {0} Mathias two object with name {1}", 
                mathiasOne.Name, mathiasTwo.Name);        
        }
    }
    public class MultibleDispatch
    {
        public void Dispatch()
        {
            Animal animal = new Animal();        
            dynamic dynamicOwnerOne = new Mathias();
            dynamic dynamicOwnerTwo = new Owner();
            animal.ShoutTwoOwners(dynamicOwnerOne, dynamicOwnerTwo);
        }
    }

    Here is the output for that example that shows that the decision which method to call is made by multible Dispach (multible parameter are evaluated at runtime to make the correct method call)
    MultibleDispatchTwoParametersOutput