[英]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.