Why does the WebGrid use dynamic in formatting?
Asked Answered
C

1

6

I'm working with the System.Web.Helpers.WebGrid in an ASP.NET MVC 3 Razor project, and I'm having trouble understanding why the format parameter for a WebGridColumn is a Func<dynamic, object>.

If I create a column like this...

grid.Column(
    format: x => string.Format("{0:d}", x.StartDate)
    );

...I don't get strong typing on the StartDate property. If I try to get around it like this...

grid.Column(
    format: (MyObjectType x) => string.Format("{0:d}", x.StartDate)
    );

...I'm told at runtime that my lambda can't be cast to a Func<dynamic, object>. Is there some way I can use a non-dynamic lambda here? Even if it's just <object, object>?

(I'm in .NET 4.0, and Func<in T, out TResult> is supposed to be contravariant on T, but I'm confused about how covariance and contravariance work with dynamic.)

Cthrine answered 5/5, 2011 at 17:34 Comment(0)
R
3

As far as the type system is concerned, dynamic is the same as object.

They cannot use a strongly-typed delegate because they don't have a strongly-typed value to pass.

Inside WebGrid, they get an Object from a PropertyDescriptor, and pass that to your delegate.

Covariance won't help here; had Func<YourType, string> been convertible to Func<object, string>, it would be possible to call it with any other type and get an invalid cast.

Rotation answered 5/5, 2011 at 17:38 Comment(7)
With object I can get an invalid cast, but with dynamic I'll get an error if StartDate doesn't exist at runtime. Six of one, half a dozen of the other. But as it is, if I change the StartDate property to, say, InitialDate, this MVC view will break at runtime; I won't be able to detect it even if I enable building views at compile time.Cthrine
@Kyralessa: You can cast in the delegate: x => string.Format("{0:d}", ((YourType)x).StartDate)Rotation
Only in the WebGridColumn's format param, x ends up as a WebGridRow so it has to be x => string.Format("{0:d}", ((MyType)x.Value).StartDate);. Rather hideous.Cthrine
Hideous and, it seems to me, entirely unnecessary. Why didn't they use generics in the WebGrid?Cthrine
@Kyralessa: To allow it to be used with things like DataTable, which aren't generic. (Or with IListSource in generic classes)Rotation
A reasonable answer, I guess, but mainly what it told me is that the WebGrid is not for a static type of guy like me. I ended up using the MvcContrib grid instead, which worked a lot better.Cthrine
@Kyralessa: See msdn.microsoft.com/en-us/magazine/hh288075.aspx, which shows you how to make a generic WebGrid wrapper.Rotation

© 2022 - 2024 — McMap. All rights reserved.