Нахождение правильного свойства, реализующего интерфейс

Итак, я подумал, что у меня есть решение для получения PropertyInfo при наличии конкретного класса и PropertyInfo для интерфейса, реализуемого конкретным классом. Вот код:

public static PropertyInfo GetImplementingProperty(Type concreteType, PropertyInfo interfaceProperty)
        {

            // do some region parameter check, skipped
            var interfaceType = interfaceProperty.DeclaringType;
            //use the set method if we have a write only property
            var getCorrectMethod = interfaceProperty.GetGetMethod() == null
                ? (Func<PropertyInfo, MethodInfo>) (p => p.GetSetMethod(true))
                : p => p.GetGetMethod(true);
            var propertyMethod = getCorrectMethod(interfaceProperty);
            var mapping = concreteType.GetInterfaceMap(interfaceType);

            MethodInfo targetMethod = null;
            for (var i = 0; i < mapping.InterfaceMethods.Length; i++)
            {
                if (mapping.InterfaceMethods[i] == propertyMethod)
                {
                    targetMethod = mapping.TargetMethods[i];
                    break;
                }
            }

            foreach (var property in concreteType.GetProperties(
                BindingFlags.Instance | BindingFlags.GetProperty |
                BindingFlags.Public | BindingFlags.NonPublic)) // include non-public!
            {
                if (targetMethod == getCorrectMethod(property)) // include non-public!
                {
                    return property;
                }
            }

            throw new InvalidOperationException("The property {0} defined on the interface {1} has not been found on the class {2}. That should never happen."
                .FormatText(interfaceProperty.Name, interfaceProperty.DeclaringType.FullName, concreteType.FullName));
        }

К сожалению, я нашел случай, когда это не удалось, и я не уверен, как это исправить. Так что у меня есть в dll класс:

public abstract class BaseClass
{
    public Guid ConfigId { get; set; }
    public virtual Guid ConfigId2 { get; set; }
}

Затем в другой DLL я делаю:

    interface INamed
    {
        Guid ConfigId { get; }
        Guid ConfigId2 { get; }
    }

    private class SuperClass : BaseClass, INamed
    {
    }

Сейчас

        ReflectionHelper.GetImplementingProperty(typeof(SuperClass), typeof(INamed).GetProperty("ConfigId2")); // this works
        ReflectionHelper.GetImplementingProperty(typeof(SuperClass), typeof(INamed).GetProperty("ConfigId")); // this fails

Любая идея, как мне сопоставить свойство ConfigId с определением свойства базового класса?

PS. У меня есть атрибуты свойств конкретного класса, поэтому мне нужно их получить.

Любая помощь приветствуется!

1 ответ

Вам нужно добавить BindingFlags.FlattenHierarchy на ваш вызов GetProperties, чтобы получить свойства родительского класса. См. Документацию по адресу https://msdn.microsoft.com/en-us/library/kyaxdd3x(v=vs.110).aspx

Другие вопросы по тегам