C# 反射调用拓展类方法
今天封装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# 反射调用拓展类方法的更多相关文章
- java黑魔法-反射机制-02-通过Java反射调用其他类方法
package com.aaron.reflect; import java.lang.reflect.Method; import java.lang.reflect.InvocationTarge ...
- python 反射调用
因为目前在写一个python的项目,用到了Python的反射机制,所以做一下笔记,把写项目过程中的感悟记下来. 先简单介绍下Demo用到的函数: sys.path 是python的模块的路径集,是一个 ...
- Unity调用Android类方法
Unity调用Android类方法 1. 添加Unity的classes.jar文件 创建一个Android工程AndroidUnityDemo. 由于Unity的版本不同,直接在Unity安装包文 ...
- C#如何反射出委托的签名,如何使用反射调用委托
本文阐述C#中如何反射出委托的签名,假如我们有委托FooDelegate定义如下 delegate double FooDelegate (string param, bool condition); ...
- 外壳exe通过反射调用dll时
外壳exe通过反射调用dll时,dll是 4.0的框架,外壳exe也需要编译成4.0的框架,如果dll本身有调用32位的dll,那么外壳exe也需要编译成32位. 调试时报的那个错,直接继续运行,不影 ...
- 从vs2010的UnitTestFramework类库提取私有方法反射调用的方法
背景 年龄大点的程序员都知道在vs2010中创建单元测试非常的简单,鼠标定位在方法名字,右键创建单元测试,就会创建一个测试方法,即使是在私有方法上也可以创建测试方法. VS2010以后就没这么简单了, ...
- VS2010 F5调试时出现:“ 尝试运行项目时出错:未捕获通过反射调用的方法引发的异常”解决
VS2010 F5调试时出现 尝试运行项目时出错:未捕获通过反射调用的方法引发的异常 两个解决方法:1) 打开项目属性,选择调试选项卡,将“启用非托管代码调试”一项钩上.2) 打开项目属性,选择调试选 ...
- 反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性、字段),而不去使用Invoke方法)
反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性.字段),而不去使用Invoke方法) 创建Delegate (1).Delegate.CreateDelegate(Type, ...
- 反射调用与Lambda表达式调用
想调用一个方法很容易,直接代码调用就行,这人人都会.其次呢,还可以使用反射.不过通过反射调用的性能会远远低于直接调用——至少从绝对时间上来看的确是这样.虽然这是个众所周知的现象,我们还是来写个程序来验 ...
随机推荐
- 超链接 a 标签点击时,弹出提示框,可以按照如下来写
onclick="return confirm('确定删除该条记录?')" 加上这条记录后,就可以在访问href属性指向的链接时,有弹出提示
- 如何把Electron做成一个Runtime,让多个应用共享同一个Electron
这个问题涉及到很多知识,而且要想把这个Runtime做好很绕. 下面我就说一下我的思路:(以下内容以Windows平台为基础,Mac平台和Linux平台还得去调查一下,才能确定是否可行) 首先,我们先 ...
- c++之面试题(2)实现字符串的分割函数SplitStr
题目描述 3.实现一个将字符串按指定字符分隔的函数,形式已经确定如下,请完成标有"//请补充"的内容. 说明:返回值为是否找到分割符(true找到,false未找到),当未找到分割 ...
- 【LeetCode】977. Squares of a Sorted Array 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 排序 日期 题目地址:https://leetcod ...
- 【九度OJ】题目1203:IP地址 解题报告
[九度OJ]题目1203:IP地址 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1203 题目描述: 输入一个ip地址串,判断是否合 ...
- 【LeetCode】39. Combination Sum 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:递归 方法二:回溯法 日期 题目地址:[htt ...
- B. Destroying Roads
Destroying Roads 题目链接 题意 n个点,m条边每两个点之间不会有两个相同的边,然后给你两个起s1,s2和终点t1,t2; 求删除最多的边后满足两个s1到t1距离\(<=l1\) ...
- Chapter 5 Interaction
目录 5.1 Interaction requires a joint intervention 5.2 Identifying interaction 5.3 Counterfactual resp ...
- WPF之AvalonEdit实现MVVM双向绑定
AvalonEdit简介 AvalonEdit是基于WPF开发的代码显示控件,默认支持多种不同语言的关键词高亮,并且可以自定义高亮配置.所以通过AvalonEdit可以快速开发出自己想要的代码编辑器. ...
- [决策树]西瓜数据graphviz可视化实现
[决策树]西瓜数据graphviz可视化实现 一.问题描述: 使用西瓜数据集构建决策树,并将构建的决策树进行可视化操作. 二.问题简析: 首先我们简单的介绍一下什么是决策树.决策树是广泛用于分类和回归 ...