Tech Off Post

Single Post Permalink

View Thread: LINQ Question
  • User profile image

    Ion Todirel wrote:
    littleguru wrote:
    does somebody know how to detect if a type is an anonymous type?
    why would you want that for?

    Well, a possible use is in the creation of custom LINQ query providers that are aiming to achieve some intelligence level. Say you have a query like this:

    var res1 = from p in products select new { p.Name, p.Price = p.UnitPrice }

    Now assume you're using this query as the basis for another query (which results in calling IQueryProvider's CreateQuery method again, causing to 'extend' the current query's expression tree), like this:

    var res2 = from p in res1 orderby p.Price descending select new { p.Name, Discount = p.Price * 0.05 }

    In this second query, you're referring to p.Price, which in reality is the original datasource's (i.e. variable product) p.UnitPrice 'column'. With anonymous types, your query provider could figure this out since it has the guarantee that what comes in to the anonymous type from the first query will be the same as what comes out when using it in a second query. Therefore, projections based on anonymous types are the only real gateways towards smart providers that allow some level of composability. So, when iterating over res2, the composed query above could be translated into one single query statement rather than one that goes to the server and another one that's executing in a LINQ to Objects fashion (sample assuming we're targeting SQL):

    SELECT [Name], 0.05 * [UnitPrice] AS [Discount] FROM Products ORDER BY [UnitPrice] DESCENDING

    On the other hand, assume you have something like this:

    var res1 = from p in products select new MyProduct(p.Name, p.UnitPrice)

    Now, if you start to write a query against res1's results, there's no way to get to know where p.Name and p.UnitPrice have gone through. Maybe MyProduct has properties with similar names, but that's not enough. Even if you'd use this:

    var res1 = from p in products select new MyProduct { p.Name, Price = p.UnitPrice }

    and refer to MyProduct's Name or Price property subsequently, there's no guarantee whatsoever that values assigned to those properties are retrieved immutably.

    So, to wrap up: an intelligent query parser could benefit from the knowledge that anonymous types expose certain semantics wrt their properties, while types provided by the developer herself put an end to query intelligence (and therefore composability).

    P.S. I've been working on some of this stuff lately on a query parser that I want to be quite intelligent; I've the same problem as littleguru mentioned but am using the heuristic I posted here at the moment to detect anonymous types.