I am trying to create a List of properties for objects. I can create a list for basic objects just fine, but if I have a situation where type object A contains a property of type object B which contains a property of type object A.... well.. then I get infinite recursion.
What I've done is added a static property to all of my objects called "RecursivePropertyList" which is a List<string>
of each property that has recursion.
So, for example:
I have a Person
class with a property called Vendor
of type Vendor
.
The Vendor
class has a property called People
which is of type List<Person>
.
In the Person
class I set the value of RecursivePropertyList
to myList.Add("Vendor.People")
.
In the Vendor
class, I set the value of RecursivePropertyList
to myList.Add("People.Vendor")
.
Then in my function that creates the property list, I check to see if the current objectname.propertyName is in the RecursivePropertyList
and if so, I don't add it to my list of properties and don't drill down into it to get its properties.
This works great in the situation described above.
However, it begins to fail when I have the following situation:
An Application
class that has a property of type List<ApplicationFunction_Application>
.
An ApplicationFunction
class that has a property of type List<ApplicationFunction_Application>
.
An ApplicationFunction_Application
class that has two properties, one of type Application
, and another of type ApplicationFunction
.
The purpose of the ApplicationFunction_Application
class is to define a many-to-many relationship between Application
and ApplicationFunction
.
In the RecursivePropertyList
of Application
I put:
myList.Add("ApplicationFunctions.Application");
In the RecursivePropertyList
of ApplicationFunction
I put:
myList.Add("Applications.ApplicationFunction");
In the RecursivePropertyList
of ApplicationFunction_Application
I put:
myList.Add("ApplicationFunction.Applications");
myList.Add("Application.ApplicationFunctions");
But, my script just keeps looping forever and never stops.
Here is the code used by the function:
First, the function that is called that begins the whole thing:
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);
}
Then the function that does the meat of the work and that calls itself recursively to generate the property list for all child objects.
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;
}
The helper function that gets the default recursive properties list:
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;
}
Any ideas on what I'm doing wrong?