Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is using dynamic types to get values from anonymous objects bad practice?

Note: My question is not about ASP.Net.

I have a GridView bound with an anonymous collection using LINQ.

I want in an event handler in the grid get a value from the bound object which is not able to cast to any static type because its type is anonymous.

To solve this problem I used dynamic type to get the value

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");
    }
}

My question is that is using the dynamic type here is a bad practice?

like image 949
Homam Avatar asked Aug 30 '26 13:08

Homam


1 Answers

I would call that a bad practice, yes. If you want to use the anonymous type in multiple places in the code then it is important enough to make it a nominal type. Remember, dynamic starts the compiler again, which is a serious performance cost, and it trades convenience for the developer in exchange for hiding bugs to be discovered by the user, which is a serious customer relations cost.

Dynamic was designed to make code that was already going to be slow and brittle more pleasant to read. If you were already going to be using reflection, or already going to be talking to a legacy COM automation object, then you were already going to be in a world of slow, dangerous code. It might as well be easy-to-read slow dangerous code. If you can avoid being in that world, do it; use a nominal type.

Alternatively, if you want to use an anonymous type and have it be statically typed, use the 'cast by example' trick:

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;
}

Sneaky, eh? The cast by example trick uses generic type inference to say "I think this object over here has the same anonymous type structure as this one here".

Note that cast by example only works in the same assembly. You cannot cast by example an anonymous type created in one assembly into an anonymous type created in another.

like image 97
Eric Lippert Avatar answered Sep 01 '26 03:09

Eric Lippert