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

Hom*_*mam 2 c# dynamic anonymous-types

注意:我的问题不是关于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");
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Eri*_*ert 17

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

动态旨在使代码已经变得缓慢而脆弱,阅读更加愉快.如果您已经要使用反射,或者已经要与传统的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>(T example, object ob) where T : class
{
    return (T)ob;
}
Run Code Online (Sandbox Code Playgroud)

偷偷摸摸,是吗?通过示例技巧演员使用泛型类型推断来说"我认为此处的此对象具有与此处相同的匿名类型结构".

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

  • @Tuzo,不,它不是"实施细节".那里的一切都按照记录的规则运作.特别是,规范说同一个程序集中两个"相同"匿名类型的用法实际上是相同的类型,这使得这个合法. (4认同)