tags:

views:

116

answers:

3

Just wanted to check to see if there's a more elegant way to accomplish this task using Linq. I'm greatly simplifying the code for brevity. I'll go into my reasons in a minute, but it goes like this:

(from t in doc.Descendants(p + "Task")
where t.Element(p + "Name") != null
select new {
     FirstName = t.FirstName,
     LastName = t.LastName,
     FullName = FirstName + " " + LastName  // Error!
}

Yes, I know it would be simple to do FullName = t.FirstName + " " + t.LastName, but let's imagine for a second that FirstName and LastName were big ugly inline calculations and not simple variables. So FullName = [big ugly calc 1] + [big ugly calc 2]. So in the spirit of DRY, is there a better way this could be done? My first thought is to write a function that gives me FirstName and LastName. But is there something better?

+6  A: 

Well, you can do:

from t in doc.Descendants(p + "Task")
where t.Element(p + "Name") != null
let FirstName = t.FirstName
let LastName = t.LastName
select new { FirstName, LastName, Fullname = FirstName + LastName }

It will be slightly inefficient in terms of the projections it's going through, but it'll work.

Slightly more efficient would be:

from t in doc.Descendants(p + "Task")
where t.Element(p + "Name") != null
select new { t.FirstName, t.LastName } into x
select new { x.FirstName, x.LastName, FullName = x.FirstName + x.LastName }
Jon Skeet
Bah, beat me to it. Do you guys get these questions a few minutes ahead of the rest of us? :)
Winston Smith
@Winston - Yeah always seems to happen to me!
Chalkey
Sweet! Thank you.
billb
+1  A: 

If you weren't doing an anonymous type, you could simply not specify the FullName at all and have it defined as a calculated field.

Example:

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FullName { get { return FirstName + " " + LastName; } }
}

and then use it in your linq statement:

(from t in doc.Descendants(p + "Task")
where t.Element(p + "Name") != null
select new Person {
     FirstName = t.FirstName,
     LastName = t.LastName
}
Joseph
+1  A: 

You can do

public void SomeClassMethod()
{
    List<Person> people = new List<Person>();

    people.Add(new Person() { FirstName = "Bob", Surname = "Smith" });
    people.Add(new Person() { FirstName = "Sally", Surname = "Jones" });

    var results =
        from p in people
        let name = p.FirstName + " " + p.Surname
        select new
        {
            FirstName = p.FirstName,
            Surname = p.Surname,
            FullName = name
        };  
}

public class Person
{
    public String FirstName { get; set; }
    public String Surname { get; set; }
}
Chalkey