The compiler only knows about an anonymous type within the method it is declared, so no, you cannot do something like that. (Of course you can pass it around, but then it would be typed as object).
You can declare a new anonymous type with both properties, but that is probably not what you want:
var anon3 = new { anon1.FirstName, anon2.Surname };
It is possible to mimic what you want using C#4's dynamic
construct, but then the return value from Union would be dynamic
, and not a strong type.
Edit in response to your comment:
Here is an example on how you could implement the Union method if you want to utilize dynamic
public static class AnonymousTypeExtension
{
public static dynamic Union(this object first, params object [] others)
{
var allObjects = new[] {first}.Concat(others);
var allProperties = allObjects.SelectMany(o => o.GetType().GetProperties(),
(o, p) => new {p.Name, Value = p.GetValue(o, null)});
IDictionary<string,object> expando = new ExpandoObject();
foreach(var property in allProperties.Where(p => !expando.ContainsKey(p.Name)))
expando.Add(property.Name,property.Value);
return expando;
}
}
This will make your example code work, with the little twist that the result of the string concatenation also will be typed dynamic, which is not an allowed input for Debug.WriteLine. This means that you will need to tell the compiler to treat it as a string first (propably not an issue in your actual usage scenario):
var anon1 = new { FirstName = "Bill" };
var anon2 = new { Surname = "Hicks" };
var anon3 = anon1.Union(anon2);
string name = anon3.FirstName + " " + anon3.Surname;
Debug.WriteLine(name);