所以这就是我想出的……这将变得冗长,而且主要是“思想流”
我有自定义 HtmlHelperExtension,并在其中:
PropertyInfo[] pInfoArray = htmlHelper.ViewData.Model.GetType().GetProperties();
PropertyInfo pInfo = GetPropertyInfo(pInfoArray, key);
此GetPropertyInfo()
方法采用key
和PropertyInfo
数组循环遍历属性,直到关键部分(使用正则表达式从字符串中删除数组的任何指示,所以我只剩下属性)与属性名称匹配。在匹配时,确定这是否是循环中的第一个循环,如果是,则将匹配的属性分配给我的 TempType
和PropertyInfo
变量。如果 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;
}
前一个方法调用下一个方法来获取嵌套的属性信息,更重要的是检测传递的ItemType 是否是一个列表(没有这个,它无法正常工作,因为它无法在列表<> 类型中找到请求的属性。我需要知道列表项类型是什么。
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 级深度测试,但无论深度如何,都应该正常工作:
- 名
- 姓
- 项目[1].sprocket
- subClass.subClassInt
- subClass.mySubClassObj.sprocketObj
- subClass.ItemsInMySubClass[1].sprocket
- subClass.ItemsInMySubClass[0].mySubClassObj.widgetObj
- subClass.ItemsInMySubClass[2].mySubClassObj.sprocketObj
如果有人有更好的解决方案,或者看到我所拥有的任何潜在问题,我欢迎反馈。