Skip to content

Instantly share code, notes, and snippets.

@danielwertheim
Created December 28, 2011 20:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save danielwertheim/1529618 to your computer and use it in GitHub Desktop.
Save danielwertheim/1529618 to your computer and use it in GitHub Desktop.
Some fun with private ctors
public static class Factory<T> where T : class
{
private static readonly Func<T> FactoryFn;
static Factory()
{
//FactoryFn = CreateUsingActivator();
FactoryFn = CreateUsingLambdas();
}
private static Func<T> CreateUsingActivator()
{
var type = typeof(T);
Func<T> f = () => Activator.CreateInstance(type, true) as T;
return f;
}
private static Func<T> CreateUsingLambdas()
{
var type = typeof(T);
var ctor = type.GetConstructor(BindingFlags.Instance | BindingFlags.CreateInstance | BindingFlags.NonPublic, null, new Type[] { }, null);
var ctorExpression = Expression.New(ctor);
return Expression.Lambda<Func<T>>(ctorExpression).Compile();
}
public static T Create(Action<T> init)
{
var instance = FactoryFn();
init(instance);
return instance;
}
}
public interface IPerson
{
string Name { get; set; }
}
public class Person : IPerson
{
public string Name { get; set; }
private Person() { }
}
class Program
{
static void Main(string[] args)
{
//TOUCH ONCE BEFORE TIMING
var touchedPerson = Factory<Person>.Create(p => p.Name = "Daniel");
for (var a = 0; a < 5; a++)
{
var sw = Stopwatch.StartNew();
for (int c = 0; c < 100000; c++)
{
var person = Factory<Person>.Create(p => p.Name = "Daniel");
var n = person.Name;
}
sw.Stop();
Console.WriteLine(sw.Elapsed.TotalMilliseconds);
}
Console.ReadKey();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment