今天封装Protobuf封包时候遇到一个问题;

Protobuf的反序列化方法MergeFrom,是写在扩展类里的;c#拓展类

通过反射获取不到这个方法,就没法使用Type来泛型封装...

然而仔细一想,拓展类不也是类吗,直接反射获取拓展类方法好了;

在看Google.Protobuf源码,找到这个类;

这个MergeFrom方法就是需要的;

那这个IMessage接口怎么办;

所有自动生成的protobuf类都只自动继承两个接口;

所以传需要序列化的类即可;

//接收到服务器消息;反序列化后执行相应路由方法
public void DispatchProto(int protoId, byte[] bytes)
{
if (!ProtoDic.ContainProtoId(protoId))
{
Logger.LogError($"Unkown ProtoId:{protoId}");
return;
}
Type protoType = ProtoDic.GetProtoTypeByProtoId(protoId);
Logger.Log($"protoId:{protoId};--typeName:{protoType.FullName}"); //打印传输获得的字节的utf-8编码
PrintUTF8Code(bytes); Type tp = typeof(Google.Protobuf.MessageExtensions); //反射获取拓展类方法MergeFrom
MethodInfo method = ReflectTool.GetExtentMethod(tp,"MergeFrom", protoType, typeof(byte[])); //反射创建实例,回调方法
object obj = ReflectTool.CreateInstance(protoType);
ReflectTool.MethodInvoke(method, obj, obj, bytes); sEvents.Enqueue(new KeyValuePair<Type, object>(protoType, obj));
}

ProtoDic存储了protoId和对应的类型Type;

ReflectTool.GetExtentMethod——封装了GetMethod方法,为了能连续传入多个参数,而不是传Type数组;

ReflectTool.MethodInvoke——和上面目的一样;

//获取扩展方法
public static MethodInfo GetExtentMethod(Type extentType, string methodName, params Type[] funcParams)
{
MethodInfo method = GetMethod(extentType, methodName, funcParams);
return method;
} public static object MethodInvoke(MethodInfo method, object obj, params object[] parameters)
{
return method.Invoke(obj, parameters);
}
//通过Type创建实例,返回Object
public static object CreateInstance(Type refType, params object[] objInitial)
{
object res = System.Activator.CreateInstance(refType, objInitial); if (res == null)
{
Logger.LogError($"Reflect create Type:{refType.FullName} is null");
} return res;
}

最后写测试代码:

pb.BroadCast结构为:

message BroadCast{
int32 PID =1;
int32 Tp = 2;
string Content = 3;
}

运行代码:

Pb.BroadCast bo = new Pb.BroadCast();
bo.PID = 1;
bo.Tp = 1;
bo.Content = "Perilla";
byte[] res = bo.ToByteArray(); //打印字节的utf-8编码
StringBuilder strBuilder = new StringBuilder();
for (int i = 0; i < res.Length; ++i)
{
strBuilder.Append(res[i]);
strBuilder.Append('-');
} Logger.Log(strBuilder.ToString());
Pb.BroadCast bo2 = new Pb.BroadCast();
bo2.MergeFrom(res);
Logger.LogFormat("{0}=={1}=={2}", bo2.PID, bo2.Tp, bo2.Content);

运行结果:

C# 反射调用拓展类方法的更多相关文章

  1. java黑魔法-反射机制-02-通过Java反射调用其他类方法

    package com.aaron.reflect; import java.lang.reflect.Method; import java.lang.reflect.InvocationTarge ...

  2. python 反射调用

    因为目前在写一个python的项目,用到了Python的反射机制,所以做一下笔记,把写项目过程中的感悟记下来. 先简单介绍下Demo用到的函数: sys.path 是python的模块的路径集,是一个 ...

  3. Unity调用Android类方法

    Unity调用Android类方法 1.  添加Unity的classes.jar文件 创建一个Android工程AndroidUnityDemo. 由于Unity的版本不同,直接在Unity安装包文 ...

  4. C#如何反射出委托的签名,如何使用反射调用委托

    本文阐述C#中如何反射出委托的签名,假如我们有委托FooDelegate定义如下 delegate double FooDelegate (string param, bool condition); ...

  5. 外壳exe通过反射调用dll时

    外壳exe通过反射调用dll时,dll是 4.0的框架,外壳exe也需要编译成4.0的框架,如果dll本身有调用32位的dll,那么外壳exe也需要编译成32位. 调试时报的那个错,直接继续运行,不影 ...

  6. 从vs2010的UnitTestFramework类库提取私有方法反射调用的方法

    背景 年龄大点的程序员都知道在vs2010中创建单元测试非常的简单,鼠标定位在方法名字,右键创建单元测试,就会创建一个测试方法,即使是在私有方法上也可以创建测试方法. VS2010以后就没这么简单了, ...

  7. VS2010 F5调试时出现:“ 尝试运行项目时出错:未捕获通过反射调用的方法引发的异常”解决

    VS2010 F5调试时出现 尝试运行项目时出错:未捕获通过反射调用的方法引发的异常 两个解决方法:1) 打开项目属性,选择调试选项卡,将“启用非托管代码调试”一项钩上.2) 打开项目属性,选择调试选 ...

  8. 反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性、字段),而不去使用Invoke方法)

    反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性.字段),而不去使用Invoke方法)   创建Delegate (1).Delegate.CreateDelegate(Type, ...

  9. 反射调用与Lambda表达式调用

    想调用一个方法很容易,直接代码调用就行,这人人都会.其次呢,还可以使用反射.不过通过反射调用的性能会远远低于直接调用——至少从绝对时间上来看的确是这样.虽然这是个众所周知的现象,我们还是来写个程序来验 ...

随机推荐

  1. 痞子衡嵌入式:把玩i.MXRT1062 TencentOS Tiny EVB_AIoT开发板(1) - 开发环境搭建与点灯

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1062 TencentOS Tiny EVB_AIoT开发板环境搭建与点灯. 腾讯 TencentOS 团队于2021年1 ...

  2. 【LeetCode】519. Random Flip Matrix 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址:https://leetcode.com/problems/random-fl ...

  3. 【LeetCode】637. Average of Levels in Binary Tree 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:DFS 方法二:BFS 日期 题目地址:ht ...

  4. 【LeetCode】477. Total Hamming Distance 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 位运算 日期 题目地址:https://leetco ...

  5. 「算法笔记」Polya 定理

    一.前置概念 接下来的这些定义摘自 置换群 - OI Wiki. 1. 群 若集合 \(s\neq \varnothing\) 和 \(S\) 上的运算 \(\cdot\) 构成的代数结构 \((S, ...

  6. pandas tutorial 2

    @ 目录 Group_By 对数据进行分组 对 group进行迭代 选择一个group get_group() Aggregations 在group的基础上传入函数整合 Transformation ...

  7. Java+Eclipse+MySQL+Swing实现学生会考成绩管理系统(免费完整项目)

    版权声明:原创不易,本文禁止抄袭.转载,侵权必究! 目录 一.需求开发文档 二.数据库设计文档 三.功能模块部分代码及效果展示 四.完整源码下载 五.作者Info 一.需求开发文档 项目完整文件列表: ...

  8. 云南农业职业技术学院 / 互联网技术学院官网 HTML5+CSS3

    HTML学完后写了,有小组成员参与开发,我只写了主页,那就只贴主页的代码出来了. 作为初学者,代码写得不太好,写博客纯属记录!有问题望指导! 码云开源仓库地址:https://gitee.com/yn ...

  9. mysql中文乱码或者中文报错

    当出现中文乱码或者执行包含中文的语句报错时,十有八九就是编码的问题,我们可以执行下面语句查看编码: SHOW VARIABLES LIKE '%char%' 显示 其中character_set_se ...

  10. Android 悬浮窗 System Alert Window

    悬浮窗能显示在其他应用上方.桌面系统例如Windows,macOS,Ubuntu,打开的程序能以窗口形式显示在屏幕上. 受限于屏幕大小,安卓系统中主要使用多任务切换的方式和分屏的方式.视频播放,视频对 ...