简体   繁体   English

用类型实例化一个类

[英]Instantiate a class with its type

I'm looking for a way faster than Activator.CreateInstance to instantiate a class from its type. 我正在寻找一种比Activator.CreateInstance更快的方法来从其类型实例化一个类。

I'm doing it this way for now: Activator.CreateInstance(typeof(LoginView)); 我现在以这种方式这样做: 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 (: 非常感谢 (:

You can use Linq Expressions as explained in this blog post . 您可以按照此博客文章中的说明使用Linq表达式。 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 如果链接断开,这是ObjectActivator委托

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

and the GetActivator method 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;
}

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. 编辑看起来类型是通用的,而不仅仅是LoginView。 You could try this: 您可以尝试以下方法:

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

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

Instead of taking a Type that returns the result of typeof , take a delegate that gets you an instance of the object: 代替采用返回typeof结果的Type ,而采用委托来获取对象的实例:

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. 调用Func委托的开销非常小。 Should be much faster than calling Activator.CreateInstance on a Type . 应该比在Type上调用Activator.CreateInstance快得多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM