DotNet:是不是可能将动态转换为接口类型

Posted

技术标签:

【中文标题】DotNet:是不是可能将动态转换为接口类型【英文标题】:DotNet: Is it possibly cast dynamic to interface typeDotNet:是否可能将动态转换为接口类型 【发布时间】:2022-01-02 18:11:42 【问题描述】:

我有一个包含一些业务逻辑的外部 DLL。 我想做这样的事情:

    在运行时加载 DLL 按某些标准过滤可用类型。 创建目标类型实例 即动态 c = Activator.CreateInstance(type); 将先前创建的实例转换为某个接口以将其传递给处理程序方法

所以外部 dll 将包含类似的内容:

namespace External.Handler.Namespace

    using System;

    public interface IHandler 
        int Process(string arg);
        int ProcessV2(string arg);
    

    public class HandlerImpl : IHandler
    
        public int Process(string arg)
        
            // ... implementation
            return 0;
        

        public int ProcessV2(string arg)
        
            // ... implementation
            return 0;
        
    

在目标服务我想加载它并尝试转换到内部接口

namespace My.Target.Namespace

    using System;
    using System.Reflection;

    public interface IInternalHandler 
        int Process(string arg)
    

    class Program
    
        static void Main(string[] args)
        
            var DLL = Assembly.LoadFile(@"path\to\dll");

            foreach(Type type in DLL.GetExportedTypes())
            
                 dynamic c = Activator.CreateInstance(type);
                 try 
                 
                     // I would like to know: how perform it?
                     var typedInstance = (IInternalInterface) c;
                     Handle(typedInstance);
                 
                 catch 
            

            Console.ReadLine();
        

        public static void Handle(IInternalHandler handler, string arg) 
            int result = handler.Process(arg);
            Console.log(result);
        
    

总结:是否可以将dynamic 转换为部分匹配的接口?

【问题讨论】:

你试过了吗:IInternalInterface c = Activator.CreateInstance(type); @PoulBak 是的,我得到了例外Unable to cast object of type 'ExternalHandlerNamespace.HandlerImpl' to type 'MyTargetNamespace.IInternalHandler'. 【参考方案1】:

您的HandlerImpl 类没有实现IInternalHandler,因此您不能将其转换为该接口。

您需要将dynamic 实例包装在一个确实实现该接口的类中。例如:

internal class InternalHandlerWrapper : IInternalHandler

    private readonly object _handler;
    
    public InternalHandlerWrapper(object handler)
    
        _handler = handler;
    
    
    public int Process(string arg)
    
        dynamic handler = _handler;
        handler.Process(arg);
    

用法:

foreach(Type type in DLL.GetExportedTypes())

    if (type.IsAbstract || type.IsInterface) continue;
    
    try 
    
        object c = Activator.CreateInstance(type);
        var typedInstance = new InternalHandlerWrapper(c);
        Handle(typedInstance);
    
    catch 

注意:GetExportedTypes 也将返回IHandler 接口本身。如果你将该类型传递给Activator.CreateInstance,你会得到一个异常。您需要从循环中过滤掉抽象和接口类型。

【讨论】:

以上是关于DotNet:是不是可能将动态转换为接口类型的主要内容,如果未能解决你的问题,请参考以下文章

转换为接口(运行时动态转换)

无法将类型为“Word.ApplicationClass”的 COM 对象强制转换为接口类型“Word._Application”

求sql中解决连接错误 无法将类型为“System.__ComObject”的 COM 对象强制转换为接口类 型

Activiti6.0 动态改变流程节点类型(普通-> 会签)

C#:私有内部接口是不是可能?

无法将类型为“Word.ApplicationClass”的 COM 对象强制转换为接口类型“Word._Application”