MVC中的C#反射PropertyInfo嵌套类



当深度超过一个级别时,是否有一种仅基于字符串值检索PropertyInfo的通用方法。

我认为这可能很简单,但我的搜索结果只有我的搜索标准那么好,我认为我在阐明正确的关键词以获得我想要的搜索结果时遇到了问题。

我希望能够做以下事情(如果密钥用于直接属性/一级,即密钥="firstName",则效果非常好):

public static PropertyInfo (this HtmlHelper htmlHelper, string key) {
     PropertyInfo pInfo = htmlHelper.ViewData.Model.GetType().GetProperty(key);
     return pInfo;
}

但是有没有一种方法可以让我单独基于字符串返回PropertyInfo当Key等于更复杂的东西时,例如嵌套类、对象、列表等。:

  • key="somelist[0].myproperty"
  • key="Items[0].someotherlist[1].someproperty"(其中Items定义为List<Item> Items {get; set;}, someotherlist is defined similarly

该方法是否具有足够的通用性,可以根据需要(定义)钻取尽可能多的级别?

下面是我的想法。。。这将变得冗长,主要是"思想流"

我有自定义的HtmlHelperExtension,其中包括:

 PropertyInfo[] pInfoArray = htmlHelper.ViewData.Model.GetType().GetProperties();
 PropertyInfo pInfo = GetPropertyInfo(pInfoArray, key);

这个GetPropertyInfo()方法采用keyPropertyInfo数组,在属性之间循环,直到密钥部分(使用regex从字符串中删除数组的任何指示,所以我只剩下属性)与属性名称匹配。在Match中,确定这是否是循环中的第一个循环,如果是,则将匹配的属性分配给我的Temp TypePropertyInfo变量。如果keyParts仍有待循环,则后续循环现在使用先前设置的临时变量和for循环索引[i]来迭代/深入类结构。每次设置pInfoTemp变量,然后设置pTypeTemp,以便下一个循环可以使用它停止的地方。

    private static PropertyInfo GetPropertyInfo(PropertyInfo[] pInfoArray, string key)
    {
        PropertyInfo pInfo = null;
        string[] keyParts = key.Split('.');
        Regex arrayRgx = new Regex("\[\d*\]");
        PropertyInfo pInfoTemp = null;
        Type pTypeTemp = null;
        foreach (PropertyInfo prop in pInfoArray)
        {
            string keyPartsTrimmed = arrayRgx.Replace(keyParts[0], ""); // removes '[#]' from string
            if (keyPartsTrimmed == prop.Name)   // match property name
            {
                for (int i = 0; i < keyParts.Count(); i++)
                {
                    if (i == 0) // initial item [0]
                    {
                        pTypeTemp = prop.PropertyType;  // gets [0]'s type
                        pInfoTemp = prop;               // assigns [0]'s property info
                    }
                    else
                    {
                        pInfoTemp = GetNestedPropertyInfo(pTypeTemp, arrayRgx.Replace(keyParts[i], "")); // gets [i]'s property info for return or next iteration
                        pTypeTemp = pInfoTemp.PropertyType; // gets [i]'s type for next iteration
                    }
                }
                pInfo = pInfoTemp;
                break;
            } 
        }
        return pInfo;
    }

下一个方法由上一个调用,用于获取嵌套的属性信息,更重要的是用于检测passedItemType是否为List(如果没有此方法,它将无法正常工作,因为它无法在List<>Type中找到所需的属性。我需要知道List项类型是什么。

    private static PropertyInfo GetNestedPropertyInfo(Type passedItemType, string passedProperty)
    {
        PropertyInfo pInfoOut = null;
        if (passedItemType.IsGenericType && passedItemType.GetGenericTypeDefinition() == typeof(List<>))
        {
            Type itemType = passedItemType.GetGenericArguments()[0];
            pInfoOut = itemType.GetProperty(passedProperty);
        }
        else
        {
            pInfoOut = passedItemType.GetProperty(passedProperty);
        }
        return pInfoOut;
    }

这目前适合我今天的需求,我已经用以下属性、列表、子类、带列表的子类等对它进行了测试。深度为4级,但无论深度如何都应该正常工作:

  • firstName
  • 姓氏
  • 项目[1].链轮
  • subClasssubClassInt
  • subClass.mySubClassObj.procketObj
  • subClass.ItemsInMySubClass[1]链轮
  • subClass.ItemsInMySubClass[0].mySubClassObj.widgetObj
  • subClass.ItemsInMySubClass[2].mySubClassObj.procketObj

如果有人有更好的解决方案,或者看到我所拥有的任何潜在问题,我欢迎反馈。

在您的情况下,最好的方法是制作一个拆分该表达式的解析器。

相关内容

  • 没有找到相关文章

最新更新