2012-03-13 32 views
0

调用一个方法,我得到了我实现接口的所有类。我想调用一个方法创建如何使用反射

var types =AppDomain.CurrentDomain.GetAssemblies().ToList() 
      .SelectMany(s => s.GetTypes()) 
      .Where(t => typeof(IManagerReport).IsAssignableFrom(t)); 

Console.WriteLine("Processing manager reports.."); 
foreach(var TheType in types) 
{ 
       //error here 
    var temptype = Activator.CreateInstance(TheType) as IManagerReport; 

    temptype.Load(); 
    temptype.Save(); 
    Console.WriteLine("Saved to: " + temptype.SavePath); 
} 

所产生错误的对象的实例时,是在这里:

无法创建接口的实例

+1

东西这在上'.SelectMany'和'.Where'之间的新行:'。凡(T!=> t.IsInterface)',看看有没有什么帮助。 – 2012-03-13 17:47:33

+0

的标题有误导之嫌,你的问题无关,与调用方法,它的一切做的事实,你想构建一个接口的实例。 – 2012-03-13 17:48:23

+0

对不起,如果你喜欢,你可以改变标题。不知道这个叫 – Luke101 2012-03-13 17:50:24

回答

4

确保您从所选取的类型中排除IManagerReport。

var types =AppDomain.CurrentDomain.GetAssemblies().ToList() 
      .SelectMany(s => s.GetTypes()) 
      .Where(t => typeof(IManagerReport).IsAssignableFrom(t) 
         && typeof(IManagerReport) != t 
         && !t.IsInterface 
         && !t.IsAbstract 
         && !t.IsGenericTypeDefinition); 

的问题是,在你的类型枚举的,你有不只是派生类型IManagerReport的,也是IManagerReport本身。你不能创建一个接口的实例,只能创建一个类。使用我发布的代码排除大多数问题项目,但我仍然会在Activator.CreateInstance上添加try/catch。你可能有派生类型没有无参数的公共构造函数。这些也会失败。

包装在一个try/catch呼叫并继续。我想说你应该在这里说明所有的可能性,但其中只有太多。考虑一些,然后也考虑到创建根本不会因为另一个原因而工作的可能性。

try { 
    var temptype = Activator.CreateInstance(TheType) as IManagerReport; 
} catch { 
    continue; 
} 
+0

完美man..Can't感谢你才好 – Luke101 2012-03-13 17:58:23

1

的这里的问题是,你IManagerReport谓语Where匹配,因此将在foreach声明的一个值。您需要Where子句中筛选出接口以及

var types =AppDomain.CurrentDomain.GetAssemblies().ToList() 
      .SelectMany(s => s.GetTypes()) 
      .Where(t => typeof(IManagerReport).IsAssignableFrom(t)); 
      .Where(t => !t.IsInterface && !t.IsAbstract); 
+0

为什么使用两个,语句?这将迭代遍历枚举,然后遍历第二次剩下的内容。这不会像在现有的.Where声明中那么简单&&。 – 2012-03-13 17:53:30

+0

@DavidMorton增加额外的Where子句是不显著的性能诽谤者。没有比在环路中使用“if”更好的了。它可以作为一个“Where”来完成,但我发现它更易于分离不同的谓词 – JaredPar 2012-03-13 17:54:53

1

尝试增加或者

.Where(t=>t.IsClass) 

.Where(t=>!t.IsInterface) 

到您的LINQ查询