我已将ASP.net GridView绑定到匿名类型的集合。
如何在RowDataBound事件处理程序中引用匿名类型的一个属性?
我已经知道如何投射匿名类型:
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个属性,我必须在我添加或重新排序匿名类型属性的任何时候在两个地方更新代码。
有没有更好的方法告诉e.Row.DataItem它具有特定类型的特定属性并强制该对象给我该值(除了创建一个类)?
答案 0 :(得分:7)
研究使用反射。
示例:
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! :)
}
错误检查和优化留给读者练习。
答案 1 :(得分:5)
更好的方法是创建一个类型来处理这个,这样你就不必进行所有的转换来使用匿名类型。
答案 2 :(得分:4)
我所做的是......例如,
string Name = (string)DataBinder.Eval(dataItem.DataItem, "Name");
...但这是在listview ItemDataBound
事件处理程序中。认为它可能对某人有用。
答案 3 :(得分:3)
你使用的方式(通过示例演员)是凌乱的,非常脆弱 - 我真的不推荐它(如果你添加一个属性,或者命名它们以不同的顺序,它会破坏;等等)。更好的方法是在投影中使用您自己的命名类型。
答案 4 :(得分:1)
不,我不相信有比这更好的方法。 C#伙伴并不真正支持在本地方法范围之外使用匿名类型(即这里你有一个匿名类型附加到你的Row对象。)
通常的建议是改造一个真正的班级。
答案 5 :(得分:0)
您用来投射匿名对象的方法(非常酷)是一种黑客行为。它的工作原理很简单,因为如果属性相同,C#编译器足够聪明,只能为整个应用程序创建一个匿名类实例。因此,使用匿名类型确实没有任何好处,因为无论如何都要在幕后创建一个类。是的,你可以破解它,你可以使用反射,但是严重,为什么要费心?在这种情况下使用匿名类型有什么好处?