1

我需要分析我的对象并在列表中显示它的一些属性。我的对象有一些属性,它们来自基类“ObjectBaseClass”,这些属性不应显示在我的列表中。

我怎么知道一个属性是否来自基类?

即我有一个接口IDisposableExtended,这个接口将在我的对象类中实现。但在我的列表中,我不想显示这两个属性“Disposable”和“Disposed”。我该如何过滤它们?

public interface IDisposableExtended : IDisposable
{
    bool Disposable { get; }
    bool Disposed { get; }
}

非常感谢!

ps 属性可以来自一个基类(1级),基类(1级)也可以有一些来自他自己的基类(2级)的属性。是这样吗,当我使用包含 BindingFlags.DeclaredOnly 的 GetProperties(flags) 时,所有来自基类(级别 1 和级别 2)的属性都会被过滤?我可以只过滤基类 1 级或 2 级吗?这意味着,我想先获取所有属性,然后手动根据它们的基类进行过滤。然后我可以控制它们以显示我需要的属性。

4

3 回答 3

1

首先,这些属性的“所有者”实际上是类,而不是接口。接口允许访问这些属性,但这些属性的声明类型仍然是类。

但是,当您通过反射发现它们时,您继承的属性将具有不同的声明类型。这是一个演示的LINQPad程序:

void Main()
{
    var derivedType = typeof(Derived);
    derivedType.GetProperties().Dump("All");
    derivedType.GetProperties(BindingFlags.DeclaredOnly
        | BindingFlags.Public | BindingFlags.Instance).Dump("Declared only");
}

public class Base
{
    public string BaseProperty { get; set; }
}

public class Derived : Base
{
    public string DerivedProperty { get; set; }
}

请注意,如果您还在 中实现接口Derived,则在转储 的属性时也会显示这些方法/属性Derived,因为它们是由该类型声明的。是的,它们用于实现接口,但它们也由类型声明(“拥有”)。

于 2014-01-16T13:16:08.787 回答
1

您应该使用Type.GetProperty(String, BindingFlags)方法重载和包含BindingFlags.DeclaredOnly将搜索限制为未继承的成员。

在此处阅读更多信息:http: //msdn.microsoft.com/en-us/library/kz0a8sxy (v=vs.110).aspx

回应评论(即使我不确定我是否理解正确)。这是一个快速程序,它将遍历类型层次结构并显示在类型本身上声明的属性,不包括每个级别的继承属性。

namespace ConsoleApplication1
{
    class ClassA
    {
        public string ClassAProp { get; set; }
    }

    class ClassB : ClassA
    {
        public string ClassBProp { get; set; }
    }

    class ClassC : ClassB
    {
        public string ClassCProp { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var c = new ClassC();
            var t = c.GetType();
            while (t.BaseType != null)
            {
                var cProps = t.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
                foreach (var p in cProps)
                {
                    Console.WriteLine("{0} defines {1}", t.Name, p.Name);
                }
                t = t.BaseType;
            }
            Console.ReadLine();
        }
    }
}

因此,您可以看到 'BindingFlags.DeclaredOnly' 仅返回在类上声明的属性。希望这有助于实现您正在寻找的东西。

注意: Type.BaseType该类型将为 null object,因为它是根类型。如果您希望循环在任何其他类型处停止,您应该可以说while (t != TypeYouWantToStopAt.GetType())

于 2014-01-16T13:18:13.527 回答
0

这与您的问题略有不同,但可能会让您对您描述的问题采取不同的方法有所了解。

您可以声明一个自定义属性,用于标记您不想列出的任何属性(或任何成员)。当您枚举对象的属性时,您可以检查它的属性并跳过您标记的任何内容。这类似于 .NET 属性编辑器控件的工作方式。

于 2014-01-16T14:14:15.953 回答