通过反射排除接口实现成员

时间:2016-08-31 08:01:46

标签: c# reflection interface

我有以下界面和实现:

"img2_"

我试图使用以下代码反映出public interface INew { string TestString { get; } } public class PurchaseOrder : INew { public string OrderNo { get; set; } public string TestString { get { return "This is a test string"; } } } 对象的OrderNo部分:

PurchaseOrder

我的输出也返回var props = p.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.FlattenHierarchy); foreach (var prop in props) { Console.WriteLine(prop.Name); } 属性。我已经搜索了排除已实现的接口成员的方法,但只能找到要包含它的项目。任何人都可以告诉我如何排除这些物品吗?

2 个答案:

答案 0 :(得分:3)

以下是使用GetInterfaceMap方法的解决方案:

var interfaceMethods = typeof(PurchaseOrder)
    .GetInterfaces()
    .Select(x => typeof(PurchaseOrder).GetInterfaceMap(x))
    .SelectMany(x => x.TargetMethods).ToArray();

var propsNotFromInterface= typeof(PurchaseOrder)
    .GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.FlattenHierarchy)
    .Where(x => !x.GetAccessors(true).Any(y => interfaceMethods.Contains(y))).ToArray();

Console.WriteLine(propsNotFromInterface.Length);

您可以非常轻松地将其重构为通用方法。

答案 1 :(得分:2)

您可以尝试排除INew中定义的属性,如:

PurchaseOrder p = new PurchaseOrder();
BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.FlattenHierarchy;
PropertyInfo[] iNewPropertyInfos = typeof(INew).GetProperties(bindingFlags);
var props = p.GetType().GetProperties(bindingFlags).Where(x => iNewPropertyInfos.All(y => y.ToString() != x.ToString()));
foreach (var prop in props)
{
    Console.WriteLine(prop.Name);
}

<强>更新

更通用的方法是将该逻辑转移到通用函数中:

private static IEnumerable<PropertyInfo> GetPropertiesExcept<T>(object p)
{
    BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly |
                                BindingFlags.FlattenHierarchy;
    PropertyInfo[] iNewPropertyInfos = typeof (T).GetProperties(bindingFlags);
    return p.GetType().GetProperties(bindingFlags).Where(x => iNewPropertyInfos.All(y => y.ToString() != x.ToString()));
}

用法:

PurchaseOrder p = new PurchaseOrder();
IEnumerable<PropertyInfo> propertiesExcept = GetPropertiesExcept<INew>(p);