创建属性树的函数?
我正在尝试创建对象的属性列表。我可以为基本对象创建一个列表,但是如果我遇到这样的情况,类型对象 A 包含类型对象 B 的属性,而类型对象 B 又包含类型对象 A 的属性.... 好吧.. 那么我会得到无限递归。 我所做的就是向我的所有对象添加一个名为“RecursivePropertyList”的静态属性,它是每个具有递归属性的 List
。
因此,例如: 我有一个 Person
类,其属性名为 Vendor
,类型为 Vendor
。 Vendor
类有一个名为 People
的属性,其类型为 List
。
在 Person
类中,我将 RecursivePropertyList
的值设置为 myList.Add("Vendor.People")
。 在 Vendor
类中,我将 RecursivePropertyList
的值设置为 myList.Add("People.Vendor")
。
然后在创建属性列表的函数中,我检查当前的 objectname.propertyName 是否在 RecursivePropertyList 中,如果是,我不会将其添加到我的属性列表中,也不会将其添加到属性列表中。深入研究它以获取其属性。
这在上述情况下非常有效。
但是,当我遇到以下情况时,它开始失败: 具有 List
类型属性的 Application
类。 具有 List
类型属性的 ApplicationFunction
类。 一个 ApplicationFunction_Application
类,具有两个属性,一个为 Application
类型,另一个为 ApplicationFunction
类型。 ApplicationFunction_Application
类的用途是定义 Application
和 ApplicationFunction
之间的多对多关系。
在 Application
的 RecursivePropertyList
中,我放置:
myList.Add("ApplicationFunctions.Application");
在 RecursivePropertyList
中ApplicationFunction
我把:
myList.Add("Applications.ApplicationFunction");
在 ApplicationFunction_Application
的 RecursivePropertyList
中我put:
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;
}
对我做错了什么有什么想法吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我还没有深入研究代码,但是您是否考虑过使用属性来表示哪些属性是递归的?这可能会让您免去维护单独的静态属性列表的麻烦。列表方法似乎很容易出现潜在的困难同步问题。
ETA:示例代码:
如果我理解正确的话,这样的东西可能适用于属性级属性。它包括一个辅助方法,用于从给定类型检索标记为递归的属性,这在构建树时可能会有所帮助。
I haven't dug into the code, yet, but have you considered using an Attribute to denote which properties are recursive? That might save you the headache of having to maintain the separate static list of properties. It seems like the list approach could be prone to potentially difficult synchrnonization issues.
ETA: Sample code:
If I'm understanding this correctly, something like this would probbaly work for a property-level attribute. It includes a helper method to retrieve the properties marked as Recursive from the given type, which might help when building the tree.