前提
- 前提是我已经定义了Protobuf需要发送的消息类型,需要紧接着定义和这些类型相匹配的处理函数
- 我可以这样写
class MsgHandler{
[MsgHandle(Msg.OnLogin)]
void HandleLogin(LoginInfo msg){...};
[MsgHandle(Msg.OnExit)]
void HandleExit(ExitInfo msg){};
}
- 我的思路是通过反射遍历这个类的所有含有特性的方法,将他们和枚举值建立映射
Dictionary<Msg,Method> dict;
...
var type = typeof(MsgHandler)
foreach method in type.GetMethods()
{
var attr = method.GetAttribute<MsgHandle>();
if(attr!=null){
dict.Add(attr.Msg, method)
}
}
...
- 问题就在于这样获得的是类的反射方法,每次调用都很费时间。
- 我看了一下别人的处理方式是这样的
- 定义接口
- 为每一个处理方法写一个实现该接口的类
- 通过反射创建该类的实例并强制转换为该接口类型
- 直接调用接口定义好的方法
interface IHandle
{
void Handle(IMessage)
}
[MsgHandle(Msg.OnLogin)]
class HandleLogin:IHandle{
void Handle(LoginInfo msg){...};
}
[MsgHandle(Msg.OnExit)]
class HandleLogin:IHandle{
void Handle(ExitInfo msg){};
}
...
Dictionary<Msg,IHandle> dict;
var types = Assemble.GetAllTypes();
foreach type in types
{
var attr = type.GetAttribute<MsgHandle>();
if(attr!=null){
var instance = Activator.Create(type) as IHandle;
dict.Add(attr.Msg, instance)
}
}
...
- 但是可以升级一下,把枚举直接去掉,直接根据消息类型来作为字典的key
interface IMsgHandler
{
public void Handle(IMessage msg);
public Type GetMsgType();
}
abstract class MsgHandle<T> : IMsgHandler where T : class
{
public Type GetMsgType()
{
return typeof(T);
}
public void Handle(IMessage msg)
{
var mapMsg = msg as T;
if (mapMsg == null)
{
throw new Exception("消息转换错误");
}
Handle(mapMsg);
}
public abstract void Handle(T msg);
}
class HandleLogin:MsgHandle<LoginInfo>{
void Handle(LoginInfo msg){...};
}
Dictionary<Type,IHandle> dict;
var types = Assemble.GetAllTypes();
foreach type in types
{
var attr = type.GetAttribute<MsgHandle>();
if(attr!=null){
var instance = Activator.Create(type) as IHandle;
var type = instance.GetType();
dict.Add(type, instance)
}
}