我在寻找一种简单的方法来查找Reflection对象上使用的所有字符串值时遇到了一些问题。
我需要递归地扫描一个对象,包括任何列表、数组以查找与值匹配的字符串。到目前为止,我正在尝试返回所有值的列表,然后我可以检查该列表,但是我遇到了一个问题,StackOverflowException如果对象包含任何循环依赖项,这可能会引发 a。
到目前为止我所拥有的:(我知道,我知道,但它正在进行中:))
private IEnumerable<string> FindStringValues(object obj)
{
    if (obj != null)
    {
        Type type = obj.GetType();
        if (type == typeof(string))
        {
            yield return (string)obj;
        }
        else if (type.IsArray)
        {
            var array = obj as Array;
            foreach (var item in array)
            {
                foreach (var str in FindStringValues(item))
                {
                    yield return str;
                }
            }
        }
        else if (type.IsClass)
        {
            FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            foreach (FieldInfo field in fields)
            {
                object fieldValue = field.GetValue(obj);
                if (fieldValue == null)
                    continue;
                foreach (var str in FindStringValues(fieldValue))
                {
                    yield return str;
                }
            }
        }
    }
}
因此,我正在尝试找到一种方法来确保它的StackOverflowException安全,如果有人可以帮助我弄清楚如何在bool找到具有提供值的匹配项时返回它,那就更好了。
编辑:
多亏了我的回答,nsinreal我才能够实现目标:) 在下面添加,以防它对其他人有帮助
public static bool FindStringValue(object obj, string valueToFind)
{
    return FindStringValue(obj, valueToFind, new List<object>());
}
private static bool FindStringValue(object obj, string valueToFind, IList<object> visitedObjects)
{
    if (obj == null && !visitedObjects.Any(item => Object.ReferenceEquals(item, obj)))
    {
        if (!(obj is string))
        {
            visitedObjects.Add(obj);
        }
        Type type = obj.GetType();
        if (type == typeof(string))
        {
            return (obj).ToString() == valueToFind;
        }
        if (typeof(IEnumerable).IsAssignableFrom(type))
        {
            var array = obj as IEnumerable;
            foreach (var item in array)
            {
                if (FindStringValue(item, valueToFind, visitedObjects))
                {
                    return true;
                }
            }
            return false;
        }
        if (type.IsClass)
        {
            FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            foreach (FieldInfo field in fields)
            {
                object item = field.GetValue(obj);
                if (item == null)
                    continue;
                if (FindStringValue(item, valueToFind, visitedObjects))
                {
                    return true;
                }
            }
        }
    }
    return false;
}