我想創建對象的屬性列表。我可以爲基本對象創建一個列表,但是如果我有一種情況,即類型對象A包含一個類型爲對象B的屬性,其中包含類型爲對象A ...的屬性,那麼我會得到無限遞歸。 我所做的是爲所有名爲「RecursivePropertyList」的對象添加一個靜態屬性,這是每個遞歸屬性的List<string>
。創建屬性樹的函數?
因此,例如: 我有一個Person
類與屬性Vendor
類型Vendor
。 Vendor
班級有一個名爲People
的房產,類型爲List<Person>
。
在Person
class I中,將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
之間的多對多關係。
在Application
的RecursivePropertyList
我把:
myList.Add("ApplicationFunctions.Application");
在ApplicationFunction
的RecursivePropertyList
我把:
myList.Add("Applications.ApplicationFunction");
在ApplicationFunction_Application
的RecursivePropertyList
我把:
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;
}
任何想法?
爲什麼你需要這個?我的第一本能是,無論你想實現什麼,都有一個更好的方法,但是因爲我不知道你想達到什麼目的,所以我不能提出任何建議。 – Timwi 2010-10-05 20:58:49
另外,你爲什麼不使用調試器?它可以確切地告訴你無限遞歸發生的位置,它可以讓你逐步找出錯誤發生的位置。 – Timwi 2010-10-05 21:00:42
我需要列表的原因如下。我想能夠指定要實例化對象的哪些屬性。我的對象的某些屬性需要第二次訪問數據庫以獲取更多數據,有時我實際上並不需要這些數據。所以我想能夠設置不應該被實例化的屬性。爲了做到這一點,我需要一個具有bool flg值的屬性列表,以確定該屬性是否應該被「填充」。希望這是有道理的?如果有更好的辦法達到這個目標,我就會全神貫注。 =) – 2010-10-05 22:59:28