ppiotrowicz
ppiotrowicz

Reputation: 4614

Get class properties without those derived from given interface

Is there a clean way to query Type for properties and filter those that came from an interface?

Let's say I have a class and an interface

public interface IFoo 
{
    string Bar { get; set; }
}

public class Foo : IFoo 
{
    public string Bar { get; set; }
    public string Baz { get; set; }
}

And I want to get an array of PropertyInfo's that contain only Baz property.

Edit:

This is what I have now ... I know it's not perfect, but it kinda does the job.

var allProperties = typeof(T).GetProperties();
var interfaceMethods = typeof(T).GetInterfaceMap(typeof(IFoo)).TargetMethods;
return allProperties.Where(x => !interfaceMethods.Contains(x.GetGetMethod()) || !interfaceMethods.Contains(x.GetSetMethod())).ToArray();

Upvotes: 0

Views: 216

Answers (2)

Dennis
Dennis

Reputation: 37770

Looks like you want to use InterfaceMapping:

    private static bool IsInterfaceImplementation(PropertyInfo p, InterfaceMapping interfaceMap)
    {
        var getterIndex = Array.IndexOf(interfaceMap.TargetMethods, p.GetGetMethod());
        var setterIndex = Array.IndexOf(interfaceMap.TargetMethods, p.GetSetMethod());

        return getterIndex != -1 || setterIndex != -1;
    }

    private static PropertyInfo[] GetPropertiesExcludeInterfaceImplementation(Type type, Type interfaceType)
    {
        var interfaceMap = type.GetInterfaceMap(interfaceType);

        return type
            .GetProperties()
            .Where(p => !IsInterfaceImplementation(p, interfaceMap))
            .ToArray();
    }

Upvotes: 1

Stephan Bauer
Stephan Bauer

Reputation: 9249

You could load all interfaces that are implemented by your class and get all the properties of these interfaces. When getting the properties of your class you can check whether the property is already defined by one of the interfaces:

var interfaceProperties = typeof(Foo)
   .GetInterfaces()
   .SelectMany( i => i.GetProperties() )
   .ToList();

var properties = typeof(Foo)
   .GetProperties()
   .Where(p => !interfaceProperties.Any( ip => ip.Name==p.Name && ip.PropertyType==p.PropertyType) );

Upvotes: 0

Related Questions