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表达式调用
想调用一个方法很容易,直接代码调用就行,这人人都会.其次呢,还可以使用反射.不过通过反射调用的性能会远远低于直接调用——至少从绝对时间上来看的确是这样.虽然这是个众所周知的现象,我们还是来写个程序来验 ...
随机推荐
- SpringBoot单元测试demo
引入maven <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- 【九度OJ】题目1444:More is better 解题报告
[九度OJ]题目1444:More is better 解题报告 标签(空格分隔): 九度OJ 原题地址:http://ac.jobdu.com/problem.php?pid=1444 题目描述: ...
- 【LeetCode】329. Longest Increasing Path in a Matrix 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/longest- ...
- 【LeetCode】784. Letter Case Permutation 解题报告 (Python&C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 回溯法 循环 日期 题目地址:https://leet ...
- 【LeetCode】139. Word Break 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- C. Tourist's Notes
C. Tourist's Notes time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- RTD2172方案|TYPEC转HDMI2.0转换器芯片|CS5265替代RTD2172
RTD2172 USB Type-C到HDMI转换器结合了USB Type-C输入接口和数字高清多媒体接口(HDMI)输出.嵌入式微控制器(MCU)基于工业标准8051内核.接收器端口将信道配置(CC ...
- Java实习生常规技术面试题每日十题Java基础(六)
目录 1.在Java语言,怎么理解goto. 2.请描述一下Java 5有哪些新特性? 3.Java 6新特性有哪些. 4.Java 7 新特性有哪些. 5.Java 8 新特性有哪些. 6.描述Ja ...
- 自学java,如何快速地找到工作
本人最近一直在帮零基础的java开发者提升能力和找工作,在这个过程中,发现零基础的java程序员,在自学和找工作时,普遍会出现一些问题,同时在实践过程中,也总结出了一些能帮零基础java开发尽快提升能 ...
- IIS部署Python-django项目
1.安装CgiModule模块 首先,IIS要部署django项目,需要CgiModule模块的支持,所以首先我们要确认这个模块是否存在 打开IIS管理器: 我这里是存在的: 如果不存在,可以自行在控 ...