나는이 방법이라고 MatchNodes이 : 기본 클래스에서 속성/필드를 포함하지 기본적으로 반사를 통해 (모두 T
객체에서 모든 재산과 필드를 얻을 수 IEnumerable<bool> MatchNodes<T>(T n1, T n2)
방지 스택 오버 플로우
등을) 그리고 그들을 비교하여 결과를 bool의 IEnumerable로 반환합니다.
원시 유형 또는 문자열을 찾으면 그 사이에 ==
을 반환하면됩니다.
컬렉션에서 파생 된 유형을 찾으면 각 구성원을 반복하고 각 구성원에 대해 MatchNodes
을 호출합니다 (아야).
다른 형식을 찾으면 각 속성/필드에 대해 MatchNodes
을 호출합니다.
내 솔루션은 분명히 스택 오버플로 예외를 요구하지만 객체가 얼마나 깊게 들어갈 지 모르기 때문에 어떻게 더 잘 만들 수 있는지 실마리가 없습니다.
코드 는 (그것이 지옥으로 추한 제발 울지 않으려 고) :
public static IEnumerable<bool> MatchNodes<T>(T n1, T n2)
{
Func<PropertyInfo, bool> func= null;
if (typeof(T) == typeof(String))
{
String str1 = n1 as String;
String str2 = n2 as String;
func = new Func<PropertyInfo, bool>((property) => str1 == str2);
}
else if (typeof(System.Collections.IEnumerable).IsAssignableFrom(typeof(T)))
{
System.Collections.IEnumerable e1 = (System.Collections.IEnumerable)n1;
System.Collections.IEnumerable e2 = (System.Collections.IEnumerable)n2;
func = new Func<PropertyInfo, bool>((property) =>
{
foreach (var v1 in e1)
{
if (e2.GetEnumerator().MoveNext())
{
var v2 = e2.GetEnumerator().Current;
if (((IEnumerable<bool>)MatchNodes(v1, v2)).All(b => b == true))
{
return false;
}
}
else
{
return false;
}
}
if (e2.GetEnumerator().MoveNext())
{
return false;
}
else return true;
});
}
else if (typeof(T).IsPrimitive || typeof(T) == typeof(Decimal))
{
func = new Func<PropertyInfo, bool>((property) => property.GetValue(n1, null) == property.GetValue(n2, null));
}
else
{
func = new Func<PropertyInfo, bool>((property) =>
((IEnumerable<bool>)MatchNodes(property.GetValue(n1, null),
property.GetValue(n2, null))).All(b => b == true));
}
foreach (PropertyInfo property in typeof(T).GetProperties().Where((property) => property.DeclaringType == typeof(T)))
{
bool result =func(property);
yield return result;
}
}
내가 찾고 있어요 것은 재귀 내 방법을 호출하지 않고 개체로 기어하는 방법입니다.
명확히 편집 예 :
public class Class1 : RandomClassWithMoreProperties{
public string Str1{get;set;}
public int Int1{get;set;}
}
public class Class2{
public List<Class1> MyClassProp1 {get;set;}
public Class1 MyClassProp2 {get;set;}
public string MyStr {get;set;}
}
MatchNodes(n1,n2)
n1.GetType()
및 n2.GetType()
는 Class2
은 반환의 경우에 true :
MyClassProp1
내부의 모든Class1
객체가 같은,321있다 모두 0Int1
는MyClassProp2
는MyStr
두 개체
동등한이고 I는 RandomClassWithMoreProperties
에서 모든 특성과 비교되지 두 개체 동일한 Str1
, Int1
을 갖는 개체.
직접 메서드를 다시 작성하지 않고 재귀 적으로 작성할 수있는 모든 메서드를 루프로 작성할 수도 있습니다. 그 어려움은 결코 사소한 일이 될 수는 없지만 그것은 알려진 CS 근본이고 제가 직접 고용 한 것입니다. – user978122
루프 일지라도 개체 그래프의 사이클을 조심해야합니다. 또한, 재귀 호출은'T' 제네릭 매개 변수로'object'를 사용합니다 - 이것은'DeclaringType == typeof (T)'를 검사하기 때문에 당신이 원하는 것이 아닐 것입니다. 너 정확히 뭘 하려구? 아마도 더 좋은 방법이있을 것입니다. –
또한 두 개의 문자열을 주면 무슨 일이 일어나는지 살펴 보자.'typeof (String) .GetProperties()'의 foreach 속성은'func'을 호출 할 것이고, 이것은'str1 == str2'이다. 이것은 아마도 당신이하고자했던 것이 아닙니다. –