Я пытаюсь создать список свойств для объектов. Я могу просто создать список для базовых объектов, но если у меня есть ситуация, когда объект типа A содержит свойство объекта типа B, которое содержит свойство объекта типа A .... ну ... тогда я получаю бесконечную рекурсию.
Я добавил статическое свойство ко всем моим объектам под названием «RecursivePropertyList», которое представляет собой List<string>
каждого свойства, имеющего рекурсию.
Так, например:
У меня есть класс Person
со свойством Vendor
типа Vendor
.
Класс Vendor
имеет свойство с именем People
типа List<Person>
.
В классе Person
я устанавливаю значение RecursivePropertyList
равным myList.Add("Vendor.People")
.
В классе Vendor
я установил значение RecursivePropertyList
равным myList.Add("People.Vendor")
.
Затем в моей функции, которая создает список свойств, я проверяю, находится ли текущее имя_объекта.propertyName в RecursivePropertyList
, и если это так, я не добавляю его в свой список свойств и не раскрываю в него, чтобы получить его свойства.
Это прекрасно работает в ситуации, описанной выше.
Однако, он начинает терпеть неудачу, когда у меня возникает следующая ситуация:
Application
класс со свойством типа List<ApplicationFunction_Application>
.
Класс ApplicationFunction
со свойством типа List<ApplicationFunction_Application>
.
Класс ApplicationFunction_Application
, который имеет два свойства, одно из которых типа Application
, а другое типа ApplicationFunction
.
Цель класса ApplicationFunction_Application
- определить отношение «многие ко многим» между Application
и ApplicationFunction
.
В RecursivePropertyList
из Application
я положил:
myList.Add("ApplicationFunctions.Application");
В RecursivePropertyList
из ApplicationFunction
я положил:
myList.Add("Applications.ApplicationFunction");
В RecursivePropertyList
из ApplicationFunction_Application
я положил:
myList.Add("ApplicationFunction.Applications");
myList.Add("Application.ApplicationFunctions");
Но мой сценарий постоянно повторяется и никогда не останавливается.
Вот код, используемый функцией:
Сначала вызывается функция, которая начинает все это:
public static EquatableList<PropertyState> FillPropertyStateList(System.Type myObjectType, ref EquatableList<PropertyState> myPropertyStateList)
{
List<string> myRecursivePropertyList = FillDefaultRecursivePropertyList(myObjectType);
return FillPropertyStateList(myObjectType, ref myPropertyStateList, string.Empty, string.Empty, myRecursivePropertyList);
}
Затем функция, выполняющая основную часть работы и рекурсивно вызывающая себя для генерации списка свойств для всех дочерних объектов.
public static EquatableList<PropertyState> FillPropertyStateList(System.Type myObjectType, ref EquatableList<PropertyState> myPropertyStateList, string myParentPrefix, string myObjectName, List<string> myRecursivePropertyList)
{
if (myPropertyStateList == null)
{
myPropertyStateList = new EquatableList<PropertyState>();
}
if (string.IsNullOrEmpty(myParentPrefix))
{
myParentPrefix = string.Empty;
}
else if (!myParentPrefix.EndsWith("."))
{
myParentPrefix = myParentPrefix + ".";
}
if (string.IsNullOrEmpty(myObjectName))
{
myObjectName = string.Empty;
}
else
{
myObjectName = myObjectName + ".";
}
foreach (System.Reflection.PropertyInfo info in myObjectType.GetProperties())
{
if (info.PropertyType.BaseType == typeof(BOBase))
{
if (!myRecursivePropertyList.Exists(delegate(string x) { return x.Equals(myObjectName + info.Name); }))
{
myPropertyStateList.Add(new PropertyState(myParentPrefix + myObjectName + info.Name, true, PropertyType.BOBase));
List<string> myChildRecursivePropertyList = FillDefaultRecursivePropertyList(info.PropertyType);
myChildRecursivePropertyList.AddRange(myRecursivePropertyList.FindAll(delegate(string x) { return Regex.IsMatch(x, info.Name + ".*"); }));
FillPropertyStateList(info.PropertyType, ref myPropertyStateList, myParentPrefix + myObjectName, info.Name, myChildRecursivePropertyList);
}
}
else if (info.PropertyType.IsGenericType
&& (info.PropertyType.BaseType.GetGenericTypeDefinition() == typeof(List<>) || info.PropertyType.BaseType.GetGenericTypeDefinition() == typeof(Library.EquatableList<>)))
{
if (!myRecursivePropertyList.Exists(delegate(string x) { return x.Equals(myObjectName + info.Name); }))
{
myPropertyStateList.Add(new PropertyState(myParentPrefix + myObjectName + info.Name, true, PropertyType.BOBaseCollection));
List<string> myChildRecursivePropertyList = FillDefaultRecursivePropertyList(info.PropertyType.BaseType.GetGenericArguments()[0]);
myChildRecursivePropertyList.AddRange(myRecursivePropertyList.FindAll(delegate(string x) { return Regex.IsMatch(x, info.Name + ".*"); }));
FillPropertyStateList(info.PropertyType.BaseType.GetGenericArguments()[0], ref myPropertyStateList, myParentPrefix + myObjectName, info.Name, myChildRecursivePropertyList);
}
}
else
{
myPropertyStateList.Add(new PropertyState(myParentPrefix + myObjectName + info.Name, true, PropertyType.Standard));
}
}
return myPropertyStateList;
}
Вспомогательная функция, которая получает список рекурсивных свойств по умолчанию:
private static List<string> FillDefaultRecursivePropertyList(System.Type myObjectType)
{
List<string> myRecursivePropertyList = new List<string>();
if (myObjectType.BaseType == typeof(BOBase))
{
System.Reflection.PropertyInfo pi = myObjectType.GetProperty("RecursivePropertyList", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
if (pi != null)
{
myRecursivePropertyList = (List<string>)pi.GetValue(null, null);
}
}
return myRecursivePropertyList;
}
Есть идеи, что я делаю не так?