This proposed interface seems fine, and it's easy to understand. The question is whether it truly addresses all extensibility requirements. That can often be really difficult figure out in advance.

Over in the other discussion, I've added [an outline of what a polymorphic reflection API might look like](https://github.com/AutoFixture/AutoFixture/issues/167#issuecomment-24884100). Given such an API, you could ask for an `IEqualityComparer<IReflectionElement>`. One way to implement that might look like this:

```C#
public class ElementComparer : IEqualityComparer<IReflectionElement>
{
    public bool Equals(IReflectionElement x, IReflectionElement y)
    {
        return new CompositeReflectionElement(x, y)
            .Accept(new ComparerVisitor())
            .Value
            .Distinct()
            .Count() == 1;
    }

    public int GetHashCode(IReflectionElement obj)
    {
        return obj
            .Accept(new ComparerVisitor())
            .Value
            .Select(x => x.GetHashCode())
            .Aggregate((x, y) => x ^ y);
    }

    private class ComparerVisitor : ReflectionVisitor<IEnumerable<Observation>>
    {
        private readonly IEnumerable<Observation> observations;

        public ComparerVisitor()
            : this(new Observation[0])
        {
        }

        private ComparerVisitor(IEnumerable<Observation> observations)
        {
            this.observations = observations;
        }

        public override IEnumerable<Observation> Value
        {
            get { return this.observations; }
        }

        public override IReflectionVisitor<IEnumerable<Observation>> Visit(FieldInfoElement fieldInfoElement)
        {
            var fi = fieldInfoElement.FieldInfo;
            return new ComparerVisitor(
                this.observations.Concat(
                    new[] { new Observation(fi.FieldType, fi.Name) }));
        }

        public override IReflectionVisitor<IEnumerable<Observation>> Visit(PropertyInfoElement propertyInfoElement)
        {
            var pi = propertyInfoElement.PropertyInfo;
            return new ComparerVisitor(
                this.observations.Concat(
                    new[] { new Observation(pi.PropertyType, pi.Name) }));
        }

        public override IReflectionVisitor<IEnumerable<Observation>> Visit(ParameterInfoElement parameterInfoElement)
        {
            var pi = parameterInfoElement.ParameterInfo;
            return new ComparerVisitor(
                this.observations.Concat(
                    new[] { new Observation(pi.ParameterType, pi.Name) }));
        }
    }

    private class Observation
    {
        private readonly Type type;
        private readonly string name;

        public Observation(Type type, string name)
        {
            this.type = type;
            this.name = name;
        }

        public override bool Equals(object obj)
        {
            var other = obj as Observation;
            if (other == null)
                return base.Equals(obj);

            return object.Equals(this.type, other.type)
                && this.name.Equals(other.name, StringComparison.OrdinalIgnoreCase);
        }

        public override int GetHashCode()
        {
            return this.type.GetHashCode() ^ this.name.ToUpperInvariant().GetHashCode();
        }
    }
}
```

OK, perhaps that looks a bit over-engineered, but OTOH, I'm quite certain that it's quite flexible :)