代码之家  ›  专栏  ›  技术社区  ›  Phil

C#将类强制转换为接口列表

  •  6
  • Phil  · 技术社区  · 12 年前

    我正在尝试动态加载一些.dll文件。这些文件是插件(目前是自己编写的),至少有一个类实现 MyInterface 。对于每个文件,我将执行以下操作:

        Dictionary<MyInterface, bool> _myList;
    
        // ...code
    
        Assembly assembly = Assembly.LoadFrom(currentFile.FullName);
        foreach (Type type in assembly.GetTypes())
        {
            var myI = type.GetInterface("MyInterface");
            if(myI != null)
            {
                if ((myI.Name == "MyInterface") && !type.IsAbstract)
                {
                    var p = Activator.CreateInstance(type);
                    _myList.Add((MyInterface)p, true);
                }
            }
        }
    

    运行此操作会导致强制转换异常,但我找不到解决方法。无论如何,我想知道为什么这根本不起作用。我正在寻找.NET Framework 3.5中的解决方案。

    发生在我身上的另一件事是 null 在里面 p 在将新条目添加到之前的点运行以下操作之后 _myList 在上面的代码中:

    var p = type.InvokeMember(null, BindingFlags.CreateInstance, null,
                              null, null) as MyInterface;
    

    这段代码是第一次尝试加载插件,我不知道为什么 p 无效的 然而 我希望有人能引导我走上正确的道路:)

    3 回复  |  直到 12 年前
        1
  •  5
  •   Sergei Rogovtcev    12 年前

    有一种更简单的方法可以检查您的类型是否可以转换到您的界面。

    Assembly assembly = Assembly.LoadFrom(currentFile.FullName);
    foreach (Type type in assembly.GetTypes())
    {
        if(!typeof(MyInterface).IsAssignableFrom(type))
            continue;
    
        var p = Activator.CreateInstance(type);
        _myList.Add((MyInterface)p, true);
    }
    

    如果 IsAssignableFrom 是错误的,那么您的继承有问题,这很可能是您的错误的原因。

        2
  •  4
  •   Indy9000    12 年前

    你真的应该读书 Plug-ins and cast exceptions Jon Skeet的文章,其中解释了您看到的行为以及如何正确地使用插件框架。

        3
  •  1
  •   Adi Lester    12 年前

    请查看以下代码。我认为 Type.IsAssignableFrom(Type type) 在这种情况下可以帮助你。

    Assembly assembly = Assembly.LoadFrom(currentFile.FullName);
    ///Get all the types defined in selected  file
    Type[] types = assembly.GetTypes();
    
    ///check if we have a compatible type defined in chosen  file?
    Type compatibleType = types.SingleOrDefault(x => typeof(MyInterface).IsAssignableFrom(x));
    
    if (compatibleType != null)
    {
        ///if the compatible type exists then we can proceed and create an instance of a platform
        found = true;
        //create an instance here
        MyInterface obj = (ALPlatform)AreateInstance(compatibleType);
    
    }