欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#反射調(diào)用拓展類方法實例代碼

 更新時間:2022年01月23日 17:21:20   作者:小紫蘇  
這篇文章主要給大家介紹了關(guān)于C#反射調(diào)用拓展類方法的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

今天封裝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來泛型封裝...

然而仔細(xì)一想,拓展類不也是類嗎,直接反射獲取拓展類方法好了;

C#反射調(diào)用拓展類

在看Google.Protobuf源碼,找到這個類;

這個MergeFrom方法就是需要的;

那這個IMessage接口怎么辦;

所有自動生成的protobuf類都只自動繼承兩個接口;

所以傳需要序列化的類即可;

//接收到服務(wù)器消息;反序列化后執(zhí)行相應(yīng)路由方法
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和對應(yīng)的類型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é) 

到此這篇關(guān)于C#反射調(diào)用拓展類方法的文章就介紹到這了,更多相關(guān)C#反射調(diào)用拓展類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論