だからここに私が思いついたものがあります...これは冗長になりつつあり、ほとんどが「思考の流れ」です
カスタムの HtmlHelperExtension があり、その中に:
PropertyInfo[] pInfoArray = htmlHelper.ViewData.Model.GetType().GetProperties();
PropertyInfo pInfo = GetPropertyInfo(pInfoArray, key);
このGetPropertyInfo()
メソッドはkey
とPropertyInfo
配列を受け取り、キー部分 (正規表現を使用して文字列から配列の表示を削除するため、プロパティのみが残ります) がプロパティ名と一致するまで、プロパティを循環します。一致すると、これがループの最初のサイクルであるかどうかを判断し、そうである場合は、一致したプロパティを一時変数Type
と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;
}
この次のメソッドは、ネストされたプロパティ情報を取得するために前のメソッドによって呼び出されます。さらに重要なことは、passedItemType が List であるかどうかを検出することです (これがないと、List<> Type で要求されたプロパティを見つけることができないため、正しく機能しません。リスト項目のタイプが何であるかを知る必要があります。
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].スプロケット
- subClass.subClassInt
- subClass.mySubClassObj.sprocketObj
- subClass.ItemsInMySubClass[1].sprocket
- subClass.ItemsInMySubClass[0].mySubClassObj.widgetObj
- subClass.ItemsInMySubClass[2].mySubClassObj.sprocketObj
誰かがより良い解決策を持っている場合、または私が持っているものに潜在的な問題がある場合は、フィードバックを歓迎します.