2014-09-30 29 views
0

我试图用已编译的lambda替换对Activator.CreateInstance(string,string)的调用。用已编译的lambda替换Activator.CreateInstance

我在这里或网上看到很多样本,但是编译时总是知道这个类型。在我的CAS它不是,调用代码和类型位于单独的库。

原始源代码如下:

System.Windows.Window myObject= 
     (System.Windows.Window)Activator.CreateInstance("MyLibrary", "MyLibrary.MyType") 
     .Unwrap(); 

重要提示:MyType的总是从System.Windows.Window派生。

我坚持用下面的代码无法编译:

Type receptionPanelViewType = Type.GetType("MyLibrary.MyType,MyLibrary"); 
ConstructorInfo ctor = receptionPanelViewType.GetConstructor(Type.EmptyTypes); 

var delegateType = typeof(Func<System.Windows.Window>).MakeGenericType(receptionPanelViewType); 
var lambda = System.Linq.Expressions.Expression.Lambda(delegateType, System.Linq.Expressions.Expression.New(ctor)); 
var constructor = lambda.Compile(); 
System.Windows.Window receptionPanelView = constructor(); 

的错误是“构造”是一个“变量”,而是使用类似“法”。

任何帮助表示赞赏。

UPDATE 1:这里的目标是使用最快的代码。当然,我会缓存编译的lambda。如果此代码要在方法中重构,则该类型将是一个参数。

+1

为什么你不希望使用更简单,更易于阅读的代码,实际上作品? – 2014-09-30 09:48:42

+0

因为我需要最快的方式来创建这些对象。问题已更新。 – 2014-09-30 13:54:57

回答

0

下可能会工作:

var receptionPanelView = constructor.DynamicInvoke() as System.Windows.Window; 
+1

即使性能的原因? – 2014-09-30 11:30:17

+0

不够公平,lambda表达式,一旦编译过,在重复使用时产生更好的性能,即不断重用反射,我会更新我的答案。 – decPL 2014-09-30 12:23:17

+0

绝对有效。 – 2014-10-01 15:35:34

0

您的问题是Compile()返回一个简单Delegate类型,因为它可以返回任何类型的委托。既然你知道什么类型将返回时,你可以简单地把授人以正确的类型,并用它作为这样的:

var constructor = (Func<System.Windows.Window>) lambda.Compile(); 
System.Windows.Window receptionPanelView = constructor(); 
+1

我可能是错的,它编译好,但在运行时抛出一个异常:无法强制'System.Func'1 [MyLibrary.MyType]类型的对象键入'System.Func'1 [System.Windows.Window]' 。 – 2014-10-01 15:38:15