使用动态类型从匿名对象获取值是不好的做法?

注意:我的问题不是关于ASP.Net。

我有一个使用LINQ与匿名集合绑定的GridView。

我想在网格中的事件处理程序中从绑定对象获取一个值,该值无法转换为任何静态类型,因为它的类型是匿名的。

为了解决这个问题,我使用动态类型来获取值

protected void MyGridView_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { dynamic dataItem = e.Row.DataItem; // getting the bound object bool isCurrentEntity = dataItem.IsCurrentEntity; if (isCurrentEntity) e.Row.Style.Add(HtmlTextWriterStyle.FontWeight, "Bold"); } } 

我的问题是,使用动态类型这是一个不好的做法?

我会称这是一种不好的做法,是的。 如果要在代码中的多个位置使用匿名类型,那么将其作为标称类型就足够了。 请记住,动态再次启动编译器 ,这是一个严重的性能成本,它为开发人员交换便利,以换取隐藏用户发现的错误 ,这是一个严重的客户关系成本。

Dynamic的设计目的是使代码变得缓慢而脆弱,阅读更加愉快。 如果您已经要使用reflection,或者已经要与传统的COM自动化对象进行对话,那么您已经处于一个缓慢而危险的代码世界中。 它也可能是易于阅读的慢速危险代码。 如果你能避免进入这个世界,那就去做吧; 使用名义类型。

或者,如果您想使用匿名类型并将其静态输入,请使用“逐个示例”技巧:

 object anon; void M1() { anon = new { X = 123, Y = 456 }; } void M2() { // we want to get anon.X, but it is anonymous. How do we // trick the compiler into it? var cast = CastByExample(new { X = 0, Y = 0 }, anon); int x = cast.X; // gets anon.X! } static T CastByExample(T example, object ob) where T : class { return (T)ob; } 

偷偷摸摸,是吗? 通过示例技巧演员使用generics类型推断来说“我认为这里的这个对象具有与此处相同的匿名类型结构”。

请注意,按示例进行的转换仅适用于同一个程序集 。 您不能通过示例将在一个程序集中创建的匿名类型转换为在另一个程序集中创建的匿名类型。