C#反射調(diào)用拓展類方法實例代碼
今天封裝Protobuf封包時候遇到一個問題;
Protobuf的反序列化方法MergeFrom,是寫在擴展類里的;
C# 類拓展方法
要求:
擴展方法類必須為靜態(tài)類;
拓展方法必須為靜態(tài)方法,參數(shù)為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());
}
}
調(diào)用:
TestExtension ts = new TestExtension(); ts.Show();
通過反射獲取不到這個方法,就沒法使用Type來泛型封裝...
然而仔細一想,拓展類不也是類嗎,直接反射獲取拓展類方法好了;
C#反射調(diào)用拓展類
在看Google.Protobuf源碼,找到這個類;

這個MergeFrom方法就是需要的;
那這個IMessage接口怎么辦;
所有自動生成的protobuf類都只自動繼承兩個接口;

所以傳需要序列化的類即可;
//接收到服務器消息;反序列化后執(zhí)行相應路由方法
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}");
//打印傳輸獲得的字節(jié)的utf-8編碼
PrintUTF8Code(bytes);
Type tp = typeof(Google.Protobuf.MessageExtensions);
//反射獲取拓展類方法MergeFrom
MethodInfo method = ReflectTool.GetExtentMethod(tp,"MergeFrom", protoType, typeof(byte[]));
//反射創(chuàng)建實例,回調(diào)方法
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方法,為了能連續(xù)傳入多個參數(shù),而不是傳Type數(shù)組;
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創(chuàng)建實例,返回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結(jié)構(gòu)為:
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();
//打印字節(jié)的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);
運行結(jié)果:

總結(jié)
到此這篇關于C#反射調(diào)用拓展類方法的文章就介紹到這了,更多相關C#反射調(diào)用拓展類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
c# 通過經(jīng)緯度查詢 具體的地址和區(qū)域名稱
最近項目需要通過經(jīng)緯度查詢 具體的地址和區(qū)域名稱,通過查詢網(wǎng)絡資源,發(fā)現(xiàn)提供的大多是得到具體的地址而對區(qū)域或城市名稱的獲取就不是很好把握;在這里自己搞了個,需要的朋友可以參考下2012-11-11
解析在內(nèi)部循環(huán)中Continue外部循環(huán)的使用詳解
本篇文章是對在內(nèi)部循環(huán)中Continue外部循環(huán)的使用進行了詳細的分析介紹,需要的朋友參考下2013-05-05
解析C#設計模式編程中外觀模式Facade Pattern的應用
這篇文章主要介紹了C#設計模式編程中外觀模式Facade Pattern的應用,外觀模式中分為門面(Facade)和子系統(tǒng)(subsystem)兩個角色來進行實現(xiàn),需要的朋友可以參考下2016-02-02
C#條件拼接Expression<Func<T, bool>>的使用
本文主要介紹了C#條件拼接Expression<Func<T, bool>>的使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02

