利用直接获取对象的各种内容信息

最近感觉在调试时总是要把一些对象的属性都打印出来,比如收到网络协议后把各个值打印出来看看。感觉可以利用反射直接获取对象的内容,这样就不用每次都手写了。

这里是unity平台的c#代码,test挂到空物体上就能执行了。因为用了反射所以先禁止在运行时执行了。

思路大概就是这样,直接上代码。

核心代码如下:

using System;
using System.Collections;
using System.Text;

public static class GetObjectInfo
{
    public static string GetObjInfo(this object obj, int maxDeep=3, bool propertie=false)
    {
#if !UNITY_EDITOR
        return "";
#endif
        _maxDeep = maxDeep;
        _propertie = propertie;
        return GetObjInfoHelp(obj, 0);
    }
    private static int _maxDeep = 3;        // 有些类拿的引用可能太复杂了,需要限制深度
    private static bool _propertie = false;  // 访问属性还是有风险的,加个开关
    private static string GetObjInfoHelp(this object t, int deep)
    {
#if !UNITY_EDITOR
        return "";
#endif
        if (t == null) { return "null"; }
        if (t.GetType().IsValueType) return t.ToString();
        if (t is string) return $"\"{t}\"";
        if (deep >= _maxDeep) return "\"深度已达最大\"";

        string tab = "";
        for (int i = 0; i < deep; i++) { tab += "\t"; }
        StringBuilder tStr = new StringBuilder();

        // 如果是容器应该把里面的东西搞出来
        var enumer = t as IEnumerable;
        if (enumer != null)
        {
            tStr.Append(tab + $"[  // {t.GetType()}\n");

            foreach (var item in enumer)
            {
                //if (item == null) continue;
                var type = item?.GetType();
                string value = GetObjInfoHelp(item, deep + 1);
                tStr.Append(tab + $"\t{value},  // {type}\n");
            }

            tStr.Append(tab + $"],\n");
            //不返回,可能还有其他字段属性
            //return tStr.ToString();
        }

        // 如果是类
        tStr.Append(tab + $"{{  // {t.GetType()}\n");

        //获取所有字段
        var fields = t.GetType().GetFields();
        foreach (var item in fields)
        {
            //如果标记为 Obsolete 就不要访问了
            if (item.IsDefined(typeof(ObsoleteAttribute), true)) { continue; }

            string value = GetObjInfoHelp(item.GetValue(t), deep + 1);
            tStr.Append(tab + $"\t\"{item.Name}\" : {value},  // {item.FieldType}\n");
        }

        //获取所有属性
        if (_propertie)
        {
            var properties = t.GetType().GetProperties();
            foreach (var item in properties)
            {
                //如果标记为 Obsolete 就不要访问了
                if (item.IsDefined(typeof(ObsoleteAttribute), true)) { continue; }
                string value;
                //this[]有可能报TargetParameterCountException异常
                try { value = GetObjInfoHelp(item.GetValue(t), deep + 1); }
                catch (Exception e) { value = "\"error!\n" + e + "\""; }
                tStr.Append(tab + $"\t\"{item.Name}\" : {value},  // {item.PropertyType}\n");
            }
        }

        tStr.Append(tab + $"}}\n");
        return tStr.ToString();
    }
}

测试代码如下:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;

public class GetObjectInfoTest : MonoBehaviour
{
    [ContextMenu("执行")]
    void Start()
    {
        StringBuilder builder = new StringBuilder();

        var obj = new Data()
        {
            numInt = 111,
            numFloat = 123.456f,
            text = "abc",
        };
        obj.left = new Data();
        obj.right = new Data();

        builder.AppendLine();
        builder.AppendLine(11.GetObjInfo());
        builder.AppendLine(11.5.GetObjInfo());
        builder.AppendLine("字符串".GetObjInfo());
        builder.AppendLine(GetObjectInfo.GetObjInfo(null));
        builder.AppendLine((new Data().GetObjInfo()));
        builder.AppendLine(obj.GetObjInfo());

        obj.right = obj;//考虑一下循环引用的问题吧
        builder.AppendLine(obj.GetObjInfo());
        obj.right = new Data();

        var list = new List() { 1, 2, 3, 4, 5 };
        builder.AppendLine(list.GetObjInfo());

        obj.list = new List() { 1, 2, 3, 4, 5 };
        builder.AppendLine(obj.GetObjInfo());

        var tf = GameObject.Find("Main Camera").GetComponent();
        builder.AppendLine(tf.GetObjInfo());

        var go = GameObject.Find("Main Camera");
        builder.AppendLine(go.GetObjInfo());

        var c = GameObject.Find("Main Camera").GetComponent();
        builder.AppendLine(c.GetObjInfo());

        var dic = new Dictionary() { { 1, 111 }, { 2, 222 }, { 3, 333 }, };
        builder.AppendLine(dic.GetObjInfo());

        var array = new Data[] { obj, obj.left, obj.right };
        builder.AppendLine(array.GetObjInfo());

        var array2 = new Data[] { obj, obj.left, null, obj.right, new SubData() };
        builder.AppendLine(array2.GetObjInfo());

        Debug.Log(builder);
    }
}
public class Data
{
    public int numInt;
    public float numFloat;
    public string text;
    public Data left;
    public Data right;
    public List list;
}
public class SubData : Data
{
    int subData;
}

测试代码的的输出如下:


11
11.5
"字符串"
null
{  // Data
	"numInt" : 0,  // System.Int32
	"numFloat" : 0,  // System.Single
	"text" : null,  // System.String
	"left" : null,  // Data
	"right" : null,  // Data
	"list" : null,  // System.Collections.Generic.List`1[System.Int32]
}

{  // Data
	"numInt" : 111,  // System.Int32
	"numFloat" : 123.456,  // System.Single
	"text" : "abc",  // System.String
	"left" : 	{  // Data
		"numInt" : 0,  // System.Int32
		"numFloat" : 0,  // System.Single
		"text" : null,  // System.String
		"left" : null,  // Data
		"right" : null,  // Data
		"list" : null,  // System.Collections.Generic.List`1[System.Int32]
	}
,  // Data
	"right" : 	{  // Data
		"numInt" : 0,  // System.Int32
		"numFloat" : 0,  // System.Single
		"text" : null,  // System.String
		"left" : null,  // Data
		"right" : null,  // Data
		"list" : null,  // System.Collections.Generic.List`1[System.Int32]
	}
,  // Data
	"list" : null,  // System.Collections.Generic.List`1[System.Int32]
}

{  // Data
	"numInt" : 111,  // System.Int32
	"numFloat" : 123.456,  // System.Single
	"text" : "abc",  // System.String
	"left" : 	{  // Data
		"numInt" : 0,  // System.Int32
		"numFloat" : 0,  // System.Single
		"text" : null,  // System.String
		"left" : null,  // Data
		"right" : null,  // Data
		"list" : null,  // System.Collections.Generic.List`1[System.Int32]
	}
,  // Data
	"right" : 	{  // Data
		"numInt" : 111,  // System.Int32
		"numFloat" : 123.456,  // System.Single
		"text" : "abc",  // System.String
		"left" : 		{  // Data
			"numInt" : 0,  // System.Int32
			"numFloat" : 0,  // System.Single
			"text" : null,  // System.String
			"left" : null,  // Data
			"right" : null,  // Data
			"list" : null,  // System.Collections.Generic.List`1[System.Int32]
		}
,  // Data
		"right" : 		{  // Data
			"numInt" : 111,  // System.Int32
			"numFloat" : 123.456,  // System.Single
			"text" : "abc",  // System.String
			"left" : "深度已达最大",  // Data
			"right" : "深度已达最大",  // Data
			"list" : null,  // System.Collections.Generic.List`1[System.Int32]
		}
,  // Data
		"list" : null,  // System.Collections.Generic.List`1[System.Int32]
	}
,  // Data
	"list" : null,  // System.Collections.Generic.List`1[System.Int32]
}

[  // System.Collections.Generic.List`1[System.Int32]
	1,  // System.Int32
	2,  // System.Int32
	3,  // System.Int32
	4,  // System.Int32
	5,  // System.Int32
],
{  // System.Collections.Generic.List`1[System.Int32]
}

{  // Data
	"numInt" : 111,  // System.Int32
	"numFloat" : 123.456,  // System.Single
	"text" : "abc",  // System.String
	"left" : 	{  // Data
		"numInt" : 0,  // System.Int32
		"numFloat" : 0,  // System.Single
		"text" : null,  // System.String
		"left" : null,  // Data
		"right" : null,  // Data
		"list" : null,  // System.Collections.Generic.List`1[System.Int32]
	}
,  // Data
	"right" : 	{  // Data
		"numInt" : 0,  // System.Int32
		"numFloat" : 0,  // System.Single
		"text" : null,  // System.String
		"left" : null,  // Data
		"right" : null,  // Data
		"list" : null,  // System.Collections.Generic.List`1[System.Int32]
	}
,  // Data
	"list" : 	[  // System.Collections.Generic.List`1[System.Int32]
		1,  // System.Int32
		2,  // System.Int32
		3,  // System.Int32
		4,  // System.Int32
		5,  // System.Int32
	],
	{  // System.Collections.Generic.List`1[System.Int32]
	}
,  // System.Collections.Generic.List`1[System.Int32]
}

[  // UnityEngine.Transform
],
{  // UnityEngine.Transform
}

{  // UnityEngine.GameObject
}

{  // UnityEngine.Camera
	"onPreCull" : null,  // UnityEngine.Camera+CameraCallback
	"onPreRender" : null,  // UnityEngine.Camera+CameraCallback
	"onPostRender" : null,  // UnityEngine.Camera+CameraCallback
}

[  // System.Collections.Generic.Dictionary`2[System.Int32,System.Int32]
	[1, 111],  // System.Collections.Generic.KeyValuePair`2[System.Int32,System.Int32]
	[2, 222],  // System.Collections.Generic.KeyValuePair`2[System.Int32,System.Int32]
	[3, 333],  // System.Collections.Generic.KeyValuePair`2[System.Int32,System.Int32]
],
{  // System.Collections.Generic.Dictionary`2[System.Int32,System.Int32]
}

[  // Data[]
		{  // Data
		"numInt" : 111,  // System.Int32
		"numFloat" : 123.456,  // System.Single
		"text" : "abc",  // System.String
		"left" : 		{  // Data
			"numInt" : 0,  // System.Int32
			"numFloat" : 0,  // System.Single
			"text" : null,  // System.String
			"left" : null,  // Data
			"right" : null,  // Data
			"list" : null,  // System.Collections.Generic.List`1[System.Int32]
		}
,  // Data
		"right" : 		{  // Data
			"numInt" : 0,  // System.Int32
			"numFloat" : 0,  // System.Single
			"text" : null,  // System.String
			"left" : null,  // Data
			"right" : null,  // Data
			"list" : null,  // System.Collections.Generic.List`1[System.Int32]
		}
,  // Data
		"list" : 		[  // System.Collections.Generic.List`1[System.Int32]
			1,  // System.Int32
			2,  // System.Int32
			3,  // System.Int32
			4,  // System.Int32
			5,  // System.Int32
		],
		{  // System.Collections.Generic.List`1[System.Int32]
		}
,  // System.Collections.Generic.List`1[System.Int32]
	}
,  // Data
		{  // Data
		"numInt" : 0,  // System.Int32
		"numFloat" : 0,  // System.Single
		"text" : null,  // System.String
		"left" : null,  // Data
		"right" : null,  // Data
		"list" : null,  // System.Collections.Generic.List`1[System.Int32]
	}
,  // Data
		{  // Data
		"numInt" : 0,  // System.Int32
		"numFloat" : 0,  // System.Single
		"text" : null,  // System.String
		"left" : null,  // Data
		"right" : null,  // Data
		"list" : null,  // System.Collections.Generic.List`1[System.Int32]
	}
,  // Data
],
{  // Data[]
}

[  // Data[]
		{  // Data
		"numInt" : 111,  // System.Int32
		"numFloat" : 123.456,  // System.Single
		"text" : "abc",  // System.String
		"left" : 		{  // Data
			"numInt" : 0,  // System.Int32
			"numFloat" : 0,  // System.Single
			"text" : null,  // System.String
			"left" : null,  // Data
			"right" : null,  // Data
			"list" : null,  // System.Collections.Generic.List`1[System.Int32]
		}
,  // Data
		"right" : 		{  // Data
			"numInt" : 0,  // System.Int32
			"numFloat" : 0,  // System.Single
			"text" : null,  // System.String
			"left" : null,  // Data
			"right" : null,  // Data
			"list" : null,  // System.Collections.Generic.List`1[System.Int32]
		}
,  // Data
		"list" : 		[  // System.Collections.Generic.List`1[System.Int32]
			1,  // System.Int32
			2,  // System.Int32
			3,  // System.Int32
			4,  // System.Int32
			5,  // System.Int32
		],
		{  // System.Collections.Generic.List`1[System.Int32]
		}
,  // System.Collections.Generic.List`1[System.Int32]
	}
,  // Data
		{  // Data
		"numInt" : 0,  // System.Int32
		"numFloat" : 0,  // System.Single
		"text" : null,  // System.String
		"left" : null,  // Data
		"right" : null,  // Data
		"list" : null,  // System.Collections.Generic.List`1[System.Int32]
	}
,  // Data
	null,  // 
		{  // Data
		"numInt" : 0,  // System.Int32
		"numFloat" : 0,  // System.Single
		"text" : null,  // System.String
		"left" : null,  // Data
		"right" : null,  // Data
		"list" : null,  // System.Collections.Generic.List`1[System.Int32]
	}
,  // Data
		{  // SubData
		"numInt" : 0,  // System.Int32
		"numFloat" : 0,  // System.Single
		"text" : null,  // System.String
		"left" : null,  // Data
		"right" : null,  // Data
		"list" : null,  // System.Collections.Generic.List`1[System.Int32]
	}
,  // SubData
],
{  // Data[]
}


UnityEngine.Debug:Log (object)
GetObjectInfoTest:Start () (at Assets/018反射获取属性/GetObjectInfoTest.cs:59)

目前感觉还有改进的空间,如缩进有时不对啥的,以后再说吧。

在项目里用了用感觉还是挺方便的。

你可能感兴趣的:(unity,c#,unity,反射,开发工具,游戏开发)