实例化具有其类型的类

时间:2013-07-24 19:39:13

标签: c# reflection activator

我正在寻找比Activator.CreateInstance更快的方法来从类型中实例化一个类。

我现在这样做:Activator.CreateInstance(typeof(LoginView));但是速度非常慢:我在实例化不同的视图时看到了一些滞后。

对我的建议? 我正在谷歌搜索它几个小时,我没有找到比这更快的方式做我想要的...:/

非常感谢(:

4 个答案:

答案 0 :(得分:4)

您可以按照此blog post中的说明使用Linq表达式。在你的情况下,它将是

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


LoginView instance = createdActivator();

如果链接关闭,则为ObjectActivator委托

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

GetActivator方法

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;
}

使用此方法相对于泛型方法的一个优点是,您可以轻松地将参数传递给构造函数,但缺点是更详细的代码。

答案 1 :(得分:1)

编辑看来该类型是通用的,而不仅仅是LoginView。你可以试试这个:

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

答案 2 :(得分:1)

您可以使用泛型。

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

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

如果您知道类型(明确使用类型),则使用第一个 第二个用于从变量推断类型:

MyType blah = MyActivator<MyType>();

SomeType someVar;
object blah = MyActivator(someVar);

答案 3 :(得分:1)

不是取Type返回typeof的结果,而是取一个让你获得该对象实例的委托:

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

如果它能让你的代码变得更容易,甚至还有一种方法可以帮助你做到这一点:

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

调用Func委托的开销非常小。应该比在Activator.CreateInstance上调用Type快得多。