[英]Get Property Value of Nested Classes Where Field or Property Names are not Known at Run Time
我正在構建一個屬性搜索解決方案,該解決方案將允許用戶在嵌套屬性列表中查找每個屬性名稱和值,而這些屬性和名稱事先都不知道。 在運行時唯一已知的類對象是父類。 在下面的示例中,我將父對象(atype)傳遞給一個方法,該方法返回(期望)所有父和子成員鍵和值的字典。
假設:每個父類都有多個嵌套類。 在下面,父項是aType。 當在運行時不知道嵌套類屬性的屬性名稱時,用簡單類型檢索父級屬性而不是嵌套類屬性是孩子的事。
我發現的唯一解決方案是屬性查找選項,其中在運行時知道完整的類路徑。 當類包含未知屬性的多個類時,這不是一個選擇。 某些嵌套類包含其他類屬性以及它們自己的字段和屬性集。 因此,不能對類深度做出任何假設。
所需:提供一個選項,用於搜索父級和所有嵌套類,而無需事先了解嵌套類的屬性名稱。
public static Dictionary<string, object> DictionaryFromType(object atype)
{
if (atype == null) return new Dictionary<string, object>();
var t = atype.GetType();
var props = t.GetProperties();
var dict = new Dictionary<string, object>();
foreach (var prp in props)
{
if (prp.PropertyType.IsClass)
{
// The property Names of the Nested Class are not known at
// this point. This is an example.
// At this point I only know the property is a class.
// Passing the property class name yields no result.
var nestedValue = GetPropertyValue(atype, "childClass.nameField");
if (nestedValue != null)
dict.Add(prp.Name, nestedValue);
}
var value = GetPropertyValue(atype, prp.Name);
if (value != null)
dict.Add(prp.Name, value);
}
return dict;
}
當提供適當的對象和嵌套時,下面的方法可以很好地工作。 它不嘗試查找僅提供對象名稱的嵌套對象。
public static object GetPropertyValue(object obj, string propertyName)
{
var propertyNames = propertyName.Split('.');
foreach (string t in propertyNames)
{
if (obj != null)
{
var propertyInfo = obj.GetType().GetProperty(t);
if (propertyInfo != null)
obj = propertyInfo.GetValue(obj);
else
obj = null;
}
}
return obj;
}
下面是我的DictionaryFromType方法的修改版本。 我使用了希思的“子屬性”查找方法來獲取第二級。 這在第二層完美地工作。 仍然需要-一種遞歸搜索每個子級中潛在子級的選項。
public static Dictionary<string, object> DictionaryFromType(object atype)
{
if (atype == null) return new Dictionary<string, object>();
var t = atype.GetType();
var props = t.GetProperties();
var dict = new Dictionary<string, object>();
try
{
foreach (var prp in props)
{
if (prp.PropertyType.IsClass)
{
// The property Names of the Nested Class are not known at this point
var nestedValue = GetNestedPropertyValue(atype, prp.Name);
if (nestedValue == null) continue;
var childType = nestedValue.GetType();
// Loop through the first Sub Class of child properties
// If this level is a Class, no properties will be returned.
// Still Needed: A way to loop through Children of Children to see if the the Property is a Class
foreach (var property in childType.GetProperties())
{
var childTypePropertyValue = GetPropertyValue(atype, prp.Name + "." + property.Name);
if (!dict.ContainsKey(property.Name) && !dict.ContainsValue(childTypePropertyValue))
{
dict.Add(property.Name, childTypePropertyValue);
}
}
}
else
{
var value = GetPropertyValue(atype, prp.Name);
if (value != null)
if (!dict.ContainsKey(prp.Name) && !dict.ContainsValue(value))
{
dict.Add(prp.Name, value);
}
}
}
return dict;
}
catch (Exception ex)
{
Log.Error("Error Building Dictionary : " + ex.Message);
}
return null;
}
您知道屬性類型是一個類(說實話,.NET中的幾乎所有東西都包括,包括String
),但是您首先需要反映該類型並枚舉其屬性,例如(基本示例;進行一些假設並避免錯誤處理)為簡潔起見):
static object GetPropertyValue(object parent, string nestedPropertyName)
{
object propertyValue = null;
var tokens = nestedPropertyName.Split('.');
foreach (var token in tokens)
{
var property = parent.GetType().GetProperty(token, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
propertyValue = property.GetValue(parent);
if (propertyValue is null) return null;
parent = propertyValue;
}
return propertyValue;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.