如何使用反射调用方法

时间:2012-03-13 17:45:38

标签: c# reflection

我得到了实现我的界面的所有类。我想在创建对象实例时调用方法

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

产生的错误在这里:

  

无法创建界面实例

3 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分: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);

答案 2 :(得分:1)

尝试添加

.Where(t=>t.IsClass)

.Where(t=>!t.IsInterface)

到您的LINQ查询