Skip to content

Instantly share code, notes, and snippets.

@rogeralsing
Created January 29, 2015 13:27
Show Gist options
  • Save rogeralsing/73bb7441c1e794e7497c to your computer and use it in GitHub Desktop.
Save rogeralsing/73bb7441c1e794e7497c to your computer and use it in GitHub Desktop.
activator vs expression
using System;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace ConsoleApplication10
{
internal delegate T ObjectActivator<out T>(params object[] args);
public class Foo
{
public Foo(int i, string s)
{
}
}
internal class Program
{
private static void Main(string[] args)
{
ObjectActivator<Foo> activator = GetActivator<Foo>(typeof (Foo).GetConstructors().First());
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
Foo tmp = activator(1, "a");
}
sw.Stop();
Console.WriteLine(sw.Elapsed);
sw = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
object tmp = Activator.CreateInstance(typeof (Foo), 1, "a");
}
sw.Stop();
Console.WriteLine(sw.Elapsed);
Console.ReadLine();
}
public static ObjectActivator<T> GetActivator<T>(ConstructorInfo ctor)
{
Type type = ctor.DeclaringType;
ParameterInfo[] paramsInfo = ctor.GetParameters();
//create a single param of type object[]
ParameterExpression param =
Expression.Parameter(typeof (object[]), "args");
var argsExp =
new Expression[paramsInfo.Length];
//pick each arg from the params array
//and create a typed expression of them
for (int i = 0; i < paramsInfo.Length; i++)
{
Expression index = Expression.Constant(i);
Type paramType = paramsInfo[i].ParameterType;
Expression paramAccessorExp =
Expression.ArrayIndex(param, index);
Expression paramCastExp =
Expression.Convert(paramAccessorExp, paramType);
argsExp[i] = paramCastExp;
}
//make a NewExpression that calls the
//ctor with the args we just created
NewExpression newExp = Expression.New(ctor, argsExp);
//create a lambda with the New
//Expression as body and our param object[] as arg
LambdaExpression lambda =
Expression.Lambda(typeof (ObjectActivator<T>), newExp, param);
//compile it
var compiled = (ObjectActivator<T>) lambda.Compile();
return compiled;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment