score:8

Accepted answer

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 }

score:2

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
}

score:2

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

Related Query

More Query from same tag