J'essaie de créer une liste de propriétés pour les objets. Je peux très bien créer une liste pour les objets basiques, mais si j'ai une situation où l'objet type A contient une propriété de type objet B qui contient une propriété de type objet A ... ben ... alors j'obtiens une récursion infinie. Ce que j'ai fait est ajouté une propriété statique à tous mes objets appelés "RecursivePropertyList" qui est un List<string>
de chaque propriété qui a la récursivité.Fonction pour créer un arbre de propriétés?
Ainsi, par exemple: J'ai une classe Person
avec une propriété appelée Vendor
de type Vendor
. La classe Vendor
a une propriété appelée People
qui est de type List<Person>
.
Dans la classe Person
, la valeur RecursivePropertyList
est définie sur myList.Add("Vendor.People")
. Dans la classe Vendor
, j'ai défini la valeur RecursivePropertyList
sur myList.Add("People.Vendor")
.
Ensuite, dans ma fonction qui crée la liste de propriétés, je vérifie pour voir si l'objectname.propertyName actuel est dans le RecursivePropertyList
et si c'est le cas, je ne l'ajoute pas à ma liste de propriétés et je ne l'analyse pas dans pour obtenir ses propriétés.
Cela fonctionne très bien dans la situation décrite ci-dessus.
Cependant, il commence à échouer lorsque j'ai la situation suivante: Une classe Application
qui a une propriété de type List<ApplicationFunction_Application>
. Classe ApplicationFunction
possédant une propriété de type List<ApplicationFunction_Application>
. Classe ApplicationFunction_Application
possédant deux propriétés, l'une de type Application
et l'autre de type ApplicationFunction
. Le but de la classe ApplicationFunction_Application
est de définir une relation many-to-many entre Application
et ApplicationFunction
.
Dans le RecursivePropertyList
de Application
je mets:
myList.Add("ApplicationFunctions.Application");
Dans le RecursivePropertyList
de ApplicationFunction
je mets:
myList.Add("Applications.ApplicationFunction");
Dans le RecursivePropertyList
de ApplicationFunction_Application
je mets:
myList.Add("ApplicationFunction.Applications");
myList.Add("Application.ApplicationFunctions");
Mais, mon script ne cesse de boucle pour toujours et ne cesse jamais.
Voici le code utilisé par la fonction:
Tout d'abord, la fonction qui est appelée qui commence la chose:
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);
}
Ensuite, la fonction qui fait la viande du travail et que les appels lui-même de manière récursive pour générer la liste de propriétés pour tous les objets enfants.
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;
}
La fonction d'aide qui obtient la liste des propriétés récursive par défaut:
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;
}
Toutes les idées sur ce que je fais mal?
Pourquoi avez-vous besoin de cela? Mon premier instinct est qu'il doit y avoir une meilleure façon de réaliser tout ce que vous essayez d'accomplir, mais comme je ne sais pas ce que vous essayez d'accomplir, je ne peux rien suggérer. – Timwi
Aussi, pourquoi n'utilisez-vous pas simplement le débogueur? Il peut vous dire exactement où se passe votre récursion infinie, et il vous permet de trouver où cela va mal. – Timwi
J'ai besoin de la liste pour la raison suivante. Je veux pouvoir spécifier les propriétés d'un objet à instancier. Certaines propriétés de mon objet nécessitent un second déplacement vers la base de données pour obtenir plus de données, et parfois je n'ai pas besoin de ces données. Je voulais donc pouvoir définir les propriétés qui ne devraient pas être instanciées. Pour ce faire, j'ai besoin d'avoir une liste de propriétés avec une valeur bool flg qui détermine si cette propriété doit être "remplie" ou non. Espérons que cela a du sens? S'il y a une meilleure façon d'y parvenir, je suis tout ouïe. =) –