views:

71

answers:

1

This is kinda theoretical question, I was looking at someone else' code (below) and my simple solution was to instantiate the collection outside linq, but I can guess there will be cases where I'd want to instantiate the objects inside the query, and perhaps only on a selection of elements. Here's a simplified example of how this was being done (badly).

var pods = (from n in ids
where new Node(Convert.ToInt32(n)).HasValue("propertyName") 
select new
{
    Id = Convert.ToInt32(n),
    Url = new Node(Convert.ToInt32(n)).Url,
    Name = new Node(Convert.ToInt32(n)).Title()
}).ToList();

Irrelevant Note: in this case the Node constructor is getting data from a memory cache.

How can I improve this example to only instantiate each object once using linq?

Cheers. Murray.

+4  A: 

Use a let clause like this:

var pods = (
    from n in ids
    let id = Convert.ToInt32(n)
    let node = new Node(id)
    where node.HasValue("propertyName") 
    select new
    {
        Id = id,
        Url = node.Url,
        Name = node.Title()
    }
).ToList();

For more information please see let clause (C# Reference):

In a query expression, it is sometimes useful to store the result of a sub-expression in order to use it in subsequent clauses. You can do this with the let keyword, which creates a new range variable and initializes it with the result of the expression you supply. Once initialized with a value, the range variable cannot be used to store another value. However, if the range variable holds a queryable type, it can be queried.

Andrew Hare
Thanks, so simple. My google skills let me down and stack overflow picked me up :-)
Myster