Question

I'm looking for a way faster than Activator.CreateInstance to instantiate a class from its type.

I'm doing it this way for now: Activator.CreateInstance(typeof(LoginView)); but it's extremly slow: I see some lags while instantiating different views.

A suggestion for me ? I'm googling it for hours now and I did not find out an faster way than this to doing what I want.. :/

Thanks a lot (:

Was it helpful?

Solution 2

You could use generics.

T MyActivator<T>() where T : new() { return new T(); }

T MyActivator<T>(T variable) where T : new() { return new T(); }

The first one is used if you know the type (explicitly use the type).
The second one is used to infer the type from a variable:

MyType blah = MyActivator<MyType>();

SomeType someVar;
object blah = MyActivator(someVar);

OTHER TIPS

You can use Linq Expressions as explained in this blog post. In your case, it would be

ConstructorInfo ctor = typeof(LoginView).GetConstructors().First();
ObjectActivator<LoginView> createdActivator = GetActivator<LoginView>(ctor);


LoginView instance = createdActivator();

In case the link goes down, this is ObjectActivator delegate

delegate T ObjectActivator<T>(params object[] args);

and the GetActivator method

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");

    Expression[] 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
    ObjectActivator<T> compiled = (ObjectActivator<T>)lambda.Compile();
    return compiled;
}

One advantage to using this method over the generic method is that you can easily pass in parameters to your constructor but the disadvantage being more verbose code.

EDIT It appears the type is generic, and not just LoginView. You could try this:

public void Foo<T>(T input) where T : new()
{
    var myInstance = new T();
}

Instead of taking a Type that returns the result of typeof, take a delegate that gets you an instance of the object:

Func<object> myActivator = () => new LoginView();

Maybe even have a method to help you do that, if it'd make it easier on your code:

public static Func<object> GetActivator<T>() where T : new()
{
    return () => new T();
}

This will have a very small overhead for calling the Func delegate. Should be much faster than calling Activator.CreateInstance on a Type.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top