C#反射调用拓展类方法实例代码

 更新时间:2022年01月23日 17:21:20   作者:小紫苏  
这篇文章主要给大家介绍了关于C#反射调用拓展类方法的相关资料,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

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

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

C# 类拓展方法

要求:

扩展方法类必须为静态类;

拓展方法必须为静态方法,参数为this+需拓展类对象;

多个类拓展方法可以写在一个拓展类中;

public class TestExtension
{
    public string Test1()
    {
        return "test";
    }
}

public static class MyExtension
{
    public static void Show(this TestExtension obj)
    {
        Debug.Log("ExtensionFunc:"+ obj.Test1());
    }
}

调用:

TestExtension ts = new TestExtension();
ts.Show();

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

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

C#反射调用拓展类

在看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#反射调用拓展类方法的文章就介绍到这了,更多相关C#反射调用拓展类内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • c#连接access数据库操作类分享

    c#连接access数据库操作类分享

    本文介绍了c#连接access数据库的方法,可以执行删除、更新、插入等操作,大家参考使用吧
    2014-01-01
  • c# 通过经纬度查询 具体的地址和区域名称

    c# 通过经纬度查询 具体的地址和区域名称

    最近项目需要通过经纬度查询 具体的地址和区域名称,通过查询网络资源,发现提供的大多是得到具体的地址而对区域或城市名称的获取就不是很好把握;在这里自己搞了个,需要的朋友可以参考下
    2012-11-11
  • WPF实现3D粒子波浪效果

    WPF实现3D粒子波浪效果

    这篇文章主要为大家详细介绍了WPF实现3D粒子波浪效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-09-09
  • c# 获得局域网主机列表实例

    c# 获得局域网主机列表实例

    c# 获得局域网主机列表实例...
    2007-03-03
  • 解析在内部循环中Continue外部循环的使用详解

    解析在内部循环中Continue外部循环的使用详解

    本篇文章是对在内部循环中Continue外部循环的使用进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C#实现的Win32控制台线程计时器功能示例

    C#实现的Win32控制台线程计时器功能示例

    这篇文章主要介绍了C#实现的Win32控制台线程计时器功能,结合实例形式分析了C#基于控制台的时间操作相关技巧,需要的朋友可以参考下
    2016-08-08
  • 解析C#设计模式编程中外观模式Facade Pattern的应用

    解析C#设计模式编程中外观模式Facade Pattern的应用

    这篇文章主要介绍了C#设计模式编程中外观模式Facade Pattern的应用,外观模式中分为门面(Facade)和子系统(subsystem)两个角色来进行实现,需要的朋友可以参考下
    2016-02-02
  • C#条件拼接Expression<Func<T, bool>>的使用

    C#条件拼接Expression<Func<T, bool>>的使用

    本文主要介绍了C#条件拼接Expression<Func<T, bool>>的使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • 总结的5个C#字符串操作方法分享

    总结的5个C#字符串操作方法分享

    这篇文章主要介绍了总结的5个C#字符串操作方法分享,本文讲解了把字符串按照分隔符转换成 List、把字符串转 按照, 分割 换为数据、得到数组列表以逗号分隔的字符串、得到字符串长度等方法,需要的朋友可以参考下
    2015-05-05
  • C#中闭包概念讲解

    C#中闭包概念讲解

    这篇文章主要介绍了C#中闭包概念讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07

最新评论