.netデータバインディング-匿名型プロパティの参照
-
03-07-2019 - |
質問
ASP.net GridViewを匿名型のコレクションにバインドしました。
RowDataBoundイベントハンドラーで匿名型のプロパティの1つを参照するにはどうすればよいですか
このような匿名型をキャストする方法はすでに知っています。
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var AnonObj = Cast(e.Row.DataItem,
new { StringProperty = "", BoolProperty = false, IntProperty = 0 });
if (AnonObj.BoolProperty)
{
e.Row.Style.Add(HtmlTextWriterStyle.Color, "Red");
}
}
}
T Cast<T>(object obj, T type)
{
return (T)obj;
}
ほとんどの場合、これは機能しますが、面倒だと思います。私の実際のコードでは、3つ以上のプロパティがあり、匿名型のプロパティを追加または並べ替えるたびに2か所でコードを更新する必要があります。
e.Row.DataItemに特定のタイプの特定のプロパティがあることを通知し、オブジェクトにその値を強制的に(クラスを作成する以外に)するより良い方法はありますか?
解決
使用方法(例によるキャスト)は乱雑であり、非常に脆弱です-私は本当に推奨しません(プロパティを追加するか、名前を付ける場合)別の順序で、それは壊れます;など)。より良いアプローチは、プロジェクションで独自の名前付きタイプを使用することです。
他のヒント
リフレクションの使用を検討してください。
例:
object o = e.Row.DataItem;
Type t = o.GetType();
PropertyInfo pi = t.GetProperty("StringProperty");
if (pi != null && pi.PropertyType == typeof(string))
{
// the property exists!
string s = pi.GetValue(o, null) as string;
// we have the value
// insert your code here
// PROFIT! :)
}
読者への演習として、エラーチェックと最適化を行いました。
より良い方法は、匿名型を使用するためにすべてのキャストを行う必要がないように、これを処理する型を作成することです。
私がしていることは...たとえば、
string Name = (string)DataBinder.Eval(dataItem.DataItem, "Name");
...しかし、これはリストビュー ItemDataBound
イベントハンドラーにあります。誰かにとって役に立つかもしれないと思った。
いいえ、これ以上良い方法はないと思います。 C#の連中は、ローカルメソッドスコープ外での匿名型の使用を実際にはサポートしていません(つまり、ここではRowオブジェクトに匿名型がアタッチされています)。
通常の提案は、代わりに実際のクラスを作成することです。
匿名オブジェクトをキャストするために使用しているメソッドは(非常にクールですが)ハックです。プロパティが同じ場合、C#コンパイラはアプリ全体に対してAnonymousクラスのインスタンスを1つだけ作成するのに十分なほどスマートであるため、動作します。とにかく、クラスはバックグラウンドで作成されるため、匿名型を使用しても実際にはメリットはありません。はい、あなたはそれをハックすることができます、あなたはリフレクションを使用することができますが、何気なく、なぜ気にしますか?この場合、匿名型を使用する利点は何ですか?