我正在尝试为对象创建属性列表。我可以很好地为基本对象创建一个列表,但是如果我有一种情况,其中类型对象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")
。
然后在我创建属性列表的函数中,我检查当前objectname.propertyName是否在RecursivePropertyList
中,如果是,我不会将它添加到我的属性列表中而不是深入研究它以获得它的属性。
这在上述情况下效果很好。
但是,当我遇到以下情况时,它会开始失败:
Application
类,其属性类型为List<ApplicationFunction_Application>
。
ApplicationFunction
类,其属性类型为List<ApplicationFunction_Application>
。
ApplicationFunction_Application
类,具有两个属性,一个属于Application
,另一个属于ApplicationFunction
。
ApplicationFunction_Application
课程的目的是定义Application
和ApplicationFunction
之间的多对多关系。
在RecursivePropertyList
的{{1}}中我放了:
Application
在myList.Add("ApplicationFunctions.Application");
的{{1}}中我放了:
RecursivePropertyList
在ApplicationFunction
的{{1}}中我放了:
myList.Add("Applications.ApplicationFunction");
RecursivePropertyList
但是,我的脚本会永远循环,永不停止。
以下是该函数使用的代码:
首先,调用的函数开始整个事情:
ApplicationFunction_Application
然后执行work of the work的函数并递归调用自身以生成所有子对象的属性列表。
myList.Add("ApplicationFunction.Applications");
获取默认递归属性列表的辅助函数:
myList.Add("Application.ApplicationFunctions");
关于我做错的任何想法?
答案 0 :(得分:0)
我还没有深入研究代码,但您是否考虑使用属性来表示哪些属性是递归的?这可能会让您省去必须维护单独的静态属性列表的麻烦。似乎列表方法可能容易出现潜在的困难同步化问题。
ETA:示例代码:
如果我正确地理解了这一点,那么像这样的东西可能会对属性级属性起作用。它包含一个帮助器方法,用于检索从给定类型标记为递归的属性,这在构建树时可能会有所帮助。
[AttributeUsage(AttributeTargets.Property)]
public class RecursivePropertyAttribute
: Attribute
{
private static Dictionary<Type, List<PropertyInfo>> _Cache = new Dictionary<Type, List<PropertyInfo>>();
public IEnumerable<PropertyInfo> GetRecursiveProperties(Type t)
{
// Check the cache for the type
if (!_Cache.ContainsKey(t))
{
// Create the entry
_Cache.Add(t, new List<PropertyInfo>());
// Add properties that have the attribute
foreach (PropertyInfo p in t.GetProperties())
{
if (p.IsDefined(typeof(RecursivePropertyAttribute), true))
_Cache[t].Add(p);
}
}
return _Cache[t];
}
}