Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过反射排除接口实现成员_C#_Reflection_Interface - Fatal编程技术网

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

C# 通过反射排除接口实现成员,c#,reflection,interface,C#,Reflection,Interface,我有以下接口和实现: 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"; } } } 我试图使用以下代码反映P

我有以下接口和实现:

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"; }
    }
}
我试图使用以下代码反映
PurchaseOrder
对象的
OrderNo
部分:

var props = p.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.FlattenHierarchy);
foreach (var prop in props)
{
    Console.WriteLine(prop.Name);
}

我的输出还返回
TestString
属性。我已经搜索了排除已实现接口成员的方法,但只能找到包含它的项。有人能告诉我如何排除这些项目吗?

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

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()));
}
私有静态IEnumerable GetPropertiesExcept(对象p)
{
BindingFlags BindingFlags=BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.declareOnly|
BindingFlags.flatterhierarchy;
PropertyInfo[]InewPropertyInfo=typeof(T).GetProperties(bindingFlags);
返回p.GetType().GetProperties(bindingFlags).Where(x=>iNewPropertyInfos.All(y=>y.ToString()!=x.ToString());
}
使用方法:

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

以下是使用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);

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

我认为您可以使用。但可能你必须小心使用层次结构。谢谢,这确实有效,但我希望有一种更通用的方法-我有几个接口。然而现在它将推动我前进!感谢更新,但是如果我有一个实现了多个显式实现的接口的类,它们仍然存在(完全限定名)。
(BindingFlags)62
?Ops,这是我使用的调试快捷方式,它的for
Public | NonPublic | Instance | Static
对我来说非常有效,即使实现了多个接口!谢谢:)