簡體   English   中英

獲取在運行時未知字段或屬性名稱的嵌套類的屬性值

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM