views:

27

answers:

1

How could it be possible to union the members of instances of two or more anonymous (or maybe not anonymous) types, to create a resulting type instance with all the members?

Pseudocode example:

var anon1 = new {FirstName = "Bill"};
var anon2 = new {Surname = "Hicks"};
var anon3 = anon1.Union(anon2);

Debug.WriteLine(anon3.FirstName + " " + anon3.Surname);

Output is: "Bill Hicks"

+2  A: 

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);
driis
Thanks. I'll investigate the use of **dynamic**, as the union result need not be a strong type.
ProfK
Beautiful 'dynamic' lesson, thank yoou very much.
ProfK