【问题标题】:How to get owner class of property in C#如何在 C# 中获取属性的所有者类
【发布时间】:2014-02-05 10:02:45
【问题描述】:

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

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

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

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

非常感谢!

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

【问题讨论】:

    标签: c# properties base-class owner


    【解决方案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 对于 object 类型将为 null,因为它是根类型。如果您希望循环在任何其他类型处停止,您应该可以说while (t != TypeYouWantToStopAt.GetType())

    【讨论】:

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

    这与您的问题略有不同,但可能会为您提供解决您所描述问题的不同方法的想法。

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

    【讨论】:

    • 感谢您的回答。我也想过这个。但是这样做太昂贵了;-)
    【解决方案3】:

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

    但是,当您通过反射发现它们时,您继承的属性将具有不同的声明类型。这是一个 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 的属性时也会显示这些方法/属性,因为它们是由该类型声明的。是的,它们用于实现接口,但它们也由类型声明(“拥有”)。

    【讨论】:

    • 属性可以来自一个基类(级别1),基类(级别1)也可以有一些属性来自他自己的基类(级别2)。是不是,当我使用包含 BindingFlags.DeclaredOnly 的 GetProperties(flags) 时,所有来自基类(级别 1 和级别 2)的属性都会被过滤?这可能吗,我只是过滤基类级别 1 或级别 2?这意味着,我想先获取所有属性,然后手动根据它们的基类进行过滤。然后我可以控制它们来显示我需要的属性。
    猜你喜欢
    • 2017-09-19
    • 1970-01-01
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-20
    • 1970-01-01
    相关资源
    最近更新 更多