我在寻找一种简单的方法来查找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;
}