• 【Unity】利用C#反射打印类的字段信息


    • 最近在用protobuf-net序列化功能生成.bytes配置文件时,遇到了需要把.bytes配置文件再另外转成Lua配置文件(Lua配置表内容举例)的需求。Lua配置文件需要记录配置类的各个字段名和具体值,不可能一个个复制粘贴来写,因为除了费心费时,还有一个原因:如果以后配置类的字段名变化(例如重构时改名、新增字段)则对应生成代码也得改,所以必须使用反射来完成生成工作。
    • 以下用StudentCfg类作为举例,使用反射打印字段名、字段值,考虑到他人设计类时可能会使用List<T>类型,也一起处理了这部分内容。
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Reflection;
    using UnityEngine;
    
    public class testMisc : MonoBehaviour
    {
        public class StudentCfg
        {
            public int id;
            public string name;
            public List<int> scoreList = new List<int>();
            private string _desc = "";
            public string desc
            {
                get { return _desc; }
                set { _desc = value; }
            }
    
        }
    
        void Start()
        {
            StudentCfg studentCfg = new StudentCfg();
            studentCfg.id = 1000;
            studentCfg.name = "丽丽";
            studentCfg.scoreList.Add(100);
            studentCfg.scoreList.Add(95);
            studentCfg.desc = "爱好:滑雪";
    
            PrintFieldInfo(studentCfg);
            PrintPropertyInfo(studentCfg);
    
        }
    
        private void PrintFieldInfo(object classInstance)
        {
            FieldInfo[] fields = classInstance.GetType().GetFields();
            foreach (FieldInfo info in fields)
            {
                object value = info.GetValue(classInstance);
                // 使用info.GetType()不会得到准确类型
                Debug.LogFormat("字段值: {0}, 字段类型:{1}", value, info.FieldType);
                if (IsListT(info.FieldType))
                {
                    // 获取List<T>的T的类型
                    Type listType = value.GetType().GetGenericArguments()[0];
                    Debug.LogFormat("列表类型: {0}", listType);
                    IEnumerable list = (IEnumerable)value;
                    foreach (var item in list)
                    {
                        Debug.LogFormat("列表 单位值: {0}", item);
                    }
                }
            }
    
        }
    
        private void PrintPropertyInfo(object classInstance)
        {
            PropertyInfo[] props = classInstance.GetType().GetProperties();
            foreach (PropertyInfo info in props)
            {
                object value = info.GetValue(classInstance, null);
                // 使用info.GetType()不会得到准确类型
                Debug.LogFormat("属性值: {0}, 属性类型:{1}", value, info.PropertyType);
                if (IsListT(info.PropertyType))
                {
                    // 获取List<T>的T的类型
                    Type listType = value.GetType().GetGenericArguments()[0];
                    Debug.LogFormat("列表类型: {0}", listType);
                    IEnumerable list = (IEnumerable)value;
                    foreach (var item in list)
                    {
                        Debug.LogFormat("列表 单位值: {0}", item);
                    }
                }
            }
    
        }
    
        private bool IsListT(Type type)
        {
            if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>))
            {
                return true;
            }
            return false;
    
        }
    
    
    
    
    }
    • 运行效果如下:

  • 相关阅读:
    Golang遍历空数组实现指定次数的循环
    关于“k8s 服务如何暴露UDP动态端口”的问题的解决
    分析fastcache和freecache(一)
    victoriaMetrics中的一些Sao操作
    victoriaMetrics无法获取抓取target的问题
    MySQL索引分类及相关概念辨析
    面试官:请用SQL模拟一个死锁
    gomicro使用Consul做服务发现的方法和原理
    gomicro集成链路跟踪的方法和中间件原理
    sqlx操作MySQL实战及其ORM原理
  • 原文地址:https://www.cnblogs.com/caiger-blog/p/14209393.html
Copyright © 2020-2023  润新知