如何将类转换为动态父接口?

时间:2017-10-14 16:13:54

标签: c# reflection

我有一个通用接口和一些相应的代码(下面的所有代码都在ClassLibrary1命名空间中):

interface IProcessor<T>
{
    void process(T message);
}

public class Second{/*Store some message*/}
public class First{/*Store some message*/}

public enum MessageType
{
    First,
    Second
}

Processor

public class Processor : IProcessor<First>,IProcessor<Second>
{
    public void process(First message){/*process the "First" type message*/}
    public void process(Second message){/*process the "Second" type message*/}
}

所以我有几个process方法的重载版本。

我写了一个dispatcher课程:

public partial class Dispatcher
{
    private const string NS_BASE = "ClassLibrary1";
    private static Processor processor = new Processor();
    static partial void Dispatch(MessageType msgType, Object message);
    static partial void Dispatch_cached(MessageType msgType, Object message);
    // basic declaration above, implemntation follows
    // message parameter corresponds with msgType.The method signature is compulsory and can't be modified()
}

我首先使用直接反射:

public partial class Dispatcher
{    
    static partial void Dispatch(MessageType msgType,Object message)
    {
        Type messageType = Type.GetType(NS_BASE + "." + msgType.ToString());
        Type processorType = typeof(Processor);
        Type[] typeArr = new Type[] { messageType };
        Object[] msgArr = new Object[] { message };
        MethodInfo processMethod = processorType.GetMethod("process", typeArr);
        processMethod.Invoke(processor, msgArr);
    }
}

使用缓存提高性能:

public partial class Dispatcher
{    
    private static Dictionary<String, MethodInfo> typeDictionary = initDict();

    private static Dictionary<String, MethodInfo> initDict()
    {
        string[] names = Enum.GetNames(typeof(MessageType));
        return names.ToDictionary(msgTypeStr => msgTypeStr, msgTypeStr =>
        {
            Type messageType = Type.GetType(NS_BASE + "." + msgTypeStr.ToString());
            Type processorType = typeof(Processor);
            Type[] typeArr = new Type[] { messageType };
            return processorType.GetMethod("process", typeArr);
        });
    }

    static partial void Dispatch_cached(MessageType msgType, Object message)
    {
        if (typeDictionary.TryGetValue(msgType.ToString(), out MethodInfo processorMethod))
        {
            Object[] msgArr = new Object[] { message };
            processorMethod.Invoke(processor, msgArr);
        }
    }
}

根据我的测试,性能实际上提高了5~6倍,但我也看到了可能的反射选择,如表达式,发射或DLR。 这些替代解决方案是否适合现场,是否会提高性能?

这些是我实际面临的问题。“如何将类转换为动态父接口?”当我尝试使用DLR解决它时,我只是想出了一个问题。

static void Dispatch_dynamic(MessageType msgType, dynamic message)
{
    processor.process(message);// I think this line will raise a runtime error
    //can I convert processor to IFoo<First/Second> type and call the processor_converted.process(message)?
}

0 个答案:

没有答案