Q:

Union of Two Objects Based on Equality of Their Members

Let us start with a class definition for the sake of example:
public class Person
{
    public string FirstName;
    public string LastName;
    public int Age;
    public int Grade;
}

Now let's assume I have a List<Person> called people containing 3 objects:
{"Robby", "Goki", 12, 8}
{"Bobby", "Goki", 10, 8}
{"Sobby", "Goki", 10, 8}

What I am looking for is some way to retrieve the following single Person object:
{null, "Goki", -1, 8}

where fields which are the same in all objects retain their value while fields which have multiple values are replaced with some invalid value.
My first thought consisted of:
Person unionMan = new Person();
if (people.Select(p => p.FirstName).Distinct().Count() == 1)
    unionMan.FirstName = people[0].FirstName;
if (people.Select(p => p.LastName).Distinct().Count() == 1)
    unionMan.LastName = people[0].LastName;
if (people.Select(p => p.Age).Distinct().Count() == 1)
    unionMan.Age = people[0].Age;
if (people.Select(p => p.Grade).Distinct().Count() == 1)
    unionMan.Grade = people[0].Grade;

Unfortunately, the real business object has many more members than four and this is both tedious to write and overwhelming for someone else to see for the first time.
I also considered somehow making use of reflection to put these repetitive checks and assignments in a loop:
string[] members = new string[] { "FirstName", "LastName", "Age", "Grade" };
foreach (string member in members)
{
    if (people.Select(p => p.**member**).Distinct().Count() == 1)
        unionMan.**member** = people[0].**member**;
}

where **member** would be however reflection would allow the retrieval and storage of that particular member (assuming it is possible).
While the first solution would work, and the second I am assuming would work, does anyone have a better alternative solution to this problem?  If not, would using reflection as described above be feasible?

A:

It's inefficient to do a distinct of all the values just to count the distinct members.  You have a shortcut scenario wherein finding one value in any of the subsequent items that does not have the same value as the first item's member means that you have an invalid state for that column.
Something like this should work, though more work would need to be done if any of the members are arrays, need recursive evaluation or other more complex logic (note I have not tested this):
public static T UnionCombine<T>(this IEnumerable<T> values) where T : new() {
    var newItem = new T();
    var properties = typeof(T).GetProperties();
    for (var prop in properties) {
        var pValueFirst = prop.GetValue(values.First(), null);
        var useDefaultValue = values.Skip(1).Any(v=>!(Object.Equals(pValueFirst, prop.GetValue(v, null))));
        if (!useDefaultValue) prop.SetValue(newItem, pValueFirst, null);
    }
    return newItem;
}

