反思:从继承的接口获取成员,但不从继承的类获取

时间:2014-07-16 11:19:54

标签: c# inheritance reflection

我相信我在那里有一个有趣的问题,因为我在研究期间无法找到关于这一点的线索。

public interface IClass
{
    int i { get; set; }
}

public class A
{
    int j { get; set; }
}

public class B : A, IClass
{
    string property { get; set; }
}

我想知道是否有可能使用Reflection来获取我的类B的所有继承成员以及继承的接口IClass,但是没有继承类A的属性。

我尝试过使用BindingFlags.DeclaredOnly,但是当我只想从接口获取那些成员时,这总是得到所有继承的成员。

请问任何想法?

- Arjune

编辑:我打算用通用类T获取接口继承的属性。 以下是我尝试过的工作,感谢您的回答:

List<PropertyInfo> properties = typeof(T).GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public).Where(x => x.DeclaringType != typeof(T).BaseType).ToList();

除了B的属性外,这允许我从IClass获取属性,但不能从类A获取属性.LINQ和DeclaringType的使用就是答案。

4 个答案:

答案 0 :(得分:1)

您可以通过多种方式解决此问题,具体取决于您的确切目标。

一个想法是正常获取所有属性,然后使用A过滤掉来自类DeclaringType的属性,例如

var typeOfA = typeof(A);
var notFromA = allMembers.Where(
    p => p.DeclaringType != typeOfA && !p.DeclaringType.IsSubclassOf(typeOfA));

当然,您可以完全忽略基类,只获取来自已实现接口的成员,例如

var members = typeof(B).GetInterfaces().SelectMany(i => i.GetMembers());

这将为您提供B的所有成员,这些成员是接口成员的实现 - 不一定是所有B的声明成员,并且它将包括A已实现的接口成员。

一般来说,正确的方法取决于具体要求,但我觉得这个问题目前的形式还不够精确。

答案 1 :(得分:1)

如果给定类型T,您希望从接口获取所有继承的成员,您可以尝试这样做:

public static IEnumerable<MemberInfo> GetAllInterfaceMembers(this Type t){
     return t.GetInterfaces().SelectMany(x => x.GetMembers());
}

答案 2 :(得分:1)

怎么样:

var members = type.GetMembers(flags).Concat(
    type.GetInterfaces().SelectMany(x => x.GetMembers(flags))).ToList();

flags是您选择的BindingFlags选项,必须包括DeclaredOnly

答案 3 :(得分:0)

这应该做到:

var allMembers = myType.GetMembers()
    .Union(myType.GetInterfaces()
    .SelectMany(i => i.GetMembers())