我有一个通用接口和一些相应的代码(下面的所有代码都在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)?
}