fork download
  1. using System;
  2. using System.Linq;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Reflection;
  6.  
  7. public class Program {
  8. static void Main(string[] args)
  9. {
  10. object x = 2;
  11. var a = new A();
  12. a.Val = x;
  13. a.array = new A[3] { a, new A() { Val = "a"}, null};
  14.  
  15.  
  16. var b = new A();
  17. b.Val = x;
  18. b.array = new A[3] { b, new A() { Val = "a"}, null};
  19.  
  20. a.array[2] = b;
  21. b.array[2] = b;
  22.  
  23. Console.WriteLine(string.Join("\n", FindStringValues(a).ToArray()));
  24. }
  25.  
  26. public class A {
  27. public A[] array {get;set;}
  28. public object Val {get;set;}
  29. }
  30.  
  31. private static IEnumerable<string> FindStringValues(object obj) {
  32. return _FindStringValues(obj, new List<object>());
  33. }
  34.  
  35. private static IEnumerable<string> _FindStringValues(object obj, IList<object> visitedObjects)
  36. {
  37. if (obj == null)
  38. yield break;
  39.  
  40. // Console.WriteLine(string.Join("; ", visitedObjects.Select(i => i.ToString()).ToArray()));
  41. if (visitedObjects.Any(item => Object.ReferenceEquals(item, obj)))
  42. yield break;
  43.  
  44. if (!(obj is string))
  45. visitedObjects.Add(obj);
  46.  
  47. Type type = obj.GetType();
  48.  
  49. if (type == typeof(string)) {
  50. yield return (obj).ToString();
  51. yield break;
  52. }
  53.  
  54. if (typeof(IEnumerable).IsAssignableFrom(type))
  55. {
  56. var array = obj as IEnumerable;
  57. foreach (var item in array)
  58. foreach (var str in _FindStringValues(item, visitedObjects))
  59. yield return str;
  60.  
  61. yield break;
  62. }
  63.  
  64. if (type.IsClass)
  65. {
  66. FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
  67. foreach (FieldInfo field in fields)
  68. {
  69. object item = field.GetValue(obj);
  70.  
  71. if (item == null)
  72. continue;
  73.  
  74.  
  75. foreach (var str in _FindStringValues(item, visitedObjects))
  76. yield return str;
  77. }
  78.  
  79. yield break;
  80. }
  81. }
  82. }
Success #stdin #stdout 0.03s 33944KB
stdin
Standard input is empty
stdout
a
a