簡體   English   中英

遞歸迭代List / Array

[英]Recursively iterate over List/Array

我是反思的新手,遞歸迭代對象的最佳方法是什么,將通用列表和普通數組作為包含其他對象的字段?

更多信息

實際上我創建了以下屬性來標記將導出用於翻譯的字段:

using System;
[AttributeUsage(AttributeTargets.Field)]
public class ExportForTranslationAttribute : System.Attribute
{
    public ExportForTranslationAttribute() { }
}

然后我從一個特定的物體開始,然后從那里深入。 (我現在復制了整個方法。)

private Int64 timesMaxDeepnessReached = 0;

private void searchForExportableStringsInObject(object obj, int deepness)
{
    if (deepness > maxDeepness)
    {
        timesMaxDeepnessReached++;
        return;
    }

    if (obj != null)
    {
        //only follow serializable objects!
        var objAttributes = obj.GetType().GetCustomAttributes(true);
        foreach (var oa in objAttributes)
        {
            if (oa.GetType() == typeof(SerializableAttribute))
            {
                var fields = obj.GetType().GetFields();
                if (fields == null || !fields.Any())
                { return; }

                foreach (var fieldInfo in fields)
                {
                    //1. handle string fields that are directly on the component
                    #region directly on object
                    var attributes = fieldInfo.GetCustomAttributes(true);

                    bool hadExportAttribute = false;

                    foreach (var a in attributes)
                    {
                        if (a.GetType() == typeof(ExportForTranslationAttribute))
                        {
                            Debug.Log("found something!");
                            hadExportAttribute = true;

                            if (fieldInfo.FieldType == typeof(string))
                            {
                                try
                                {
                                    Debug.Log("info.GetValue= " + fieldInfo.GetValue(obj));
                                    addKeyWhenNotExisting((string)fieldInfo.GetValue(obj));
                                }
                                catch (Exception ex) { Debug.Log("error while getting value to export: " + ex); }
                            }
                            else if (fieldInfo.FieldType == typeof(string[]))
                            {
                                Debug.Log("found string[]!");
                                try
                                {
                                    Debug.Log("info.GetValue= " + fieldInfo.GetValue(obj));
                                    foreach (var item in (string[])fieldInfo.GetValue(obj))
                                    {
                                        addKeyWhenNotExisting(item);
                                    }
                                }
                                catch (Exception ex) { Debug.Log("error while getting value to export: " + ex); }
                            }
                            else if (fieldInfo.FieldType == typeof(List<string>))
                            {
                                Debug.Log("found List<string>!");
                                try
                                {
                                    Debug.Log("info.GetValue= " + fieldInfo.GetValue(obj));
                                    foreach (var item in (List<string>)fieldInfo.GetValue(obj))
                                    {
                                        addKeyWhenNotExisting(item);
                                    }
                                }
                                catch (Exception ex) { Debug.Log("error while getting value to export: " + ex); }
                            }
                            else
                            {
                                Debug.LogWarning("Can only add ExportForTranslation-Attribute to string values and collection of string values. Not on the type: " + fieldInfo.FieldType);
                            }
                        }
                    }
                    #endregion //directly on object
                }
            }
            else if (oa.GetType() == typeof(List<>))
            {
                try
                {
                    foreach (var item in (IList)oa)
                    {
                        searchForExportableStringsInObject(item, ++deepness);
                    }
                }
                catch (Exception ex) { }//{ Debug.Log("error while getting value to export: " + ex); }
            }
            else if (oa.GetType() == typeof(Array))
            {
                try
                {
                    foreach (var item in (Array)oa)
                    {
                        searchForExportableStringsInObject(item, ++deepness);
                    }
                }
                catch (Exception ex) { }//{ Debug.Log("error while getting value to export: " + ex); }
            }
        }
    }
    else
    {
        return;
    }
}

oa.GetType()獲取實例的類型,而不是您需要oa.PropertyType的屬性的類型。

編輯

我可能已經四處走動,把它放在一起,我打賭有更好的,或者至少更簡潔的方式,但也許這就像你在尋找的東西:

    class Program
    {
        static void Main(string[] args)
        {
            var testType = new TestType {GenList = new List<string> {"test", "type"}};

            foreach(var prop in typeof (TestType).GetProperties())
            {
                if (prop.PropertyType.IsGenericType)
                {
                    var genericTypeArgs = prop.PropertyType.GetGenericArguments();

                    if (genericTypeArgs.Length!=1 || !(genericTypeArgs[0] == typeof(string)))
                         continue;

                    var genEnum = typeof (IEnumerable<>).MakeGenericType(genericTypeArgs);

                    if (genEnum.IsAssignableFrom(prop.PropertyType))
                    {
                        var propVal = (IList<string>)prop.GetValue(testType, BindingFlags.GetProperty, null, null, null);

                        foreach (var item in propVal)
                            Console.WriteLine(item);
                    }
                }
            }

            Console.ReadLine();
        }
    }

    public class TestType
    {
        public IList<string> GenList { get; set; }
    }

屬性永遠不是List<> 所以oa.GetType() == typeof(List<>)將始終為false。

也許您希望使用GetFields()獲取字段,或使用GetProperties()獲取屬性,而不是獲取自定義屬性。

您可能還想檢查類型是否實現IEnumerable<T>而不是檢查它是否與List<T>相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM