如何通过反射查找类型的非继承属性

时间:2014-01-22 05:29:08

标签: c# reflection

我想从一个以特定类型声明的类中检索属性,不包括从基类继承的类。

当然这是一个简单的例子,但我想提取最简单的代码。

真实情况有点复杂,所以我真的不想改变方法。

这是我的代码:

class Program
{
    static void Main(string[] args)
    {
        MyVehicles vehicles = new MyVehicles();

        Type objectToInspectType = vehicles.GetType();

        PropertyInfo[] propertyInfos = objectToInspectType.GetProperties(); 

        foreach (PropertyInfo item in propertyInfos)
        {
            Console.WriteLine(item.PropertyType.Name); // Return Vehicle, Vehicle instead of Car, Car
        }

        Console.ReadKey();
    }
}

public class Vehicle
{
    public Vehicle()
    {
        WheelCount = 4;
    }

    public int WheelCount { get; set; }
}

public class Car : Vehicle
{
    public Car()
    {
        Color = 10;
    }

    public int Color { get; set; }
}

public class MyVehicles
{
    public MyVehicles()
    {
        vehicle1 = new Car();
        vehicle2 = new Car();
    }

    public Vehicle vehicle1 { get; set; }
    public Vehicle vehicle2 { get; set; }
}

我想要两个属性(Car& Car而不是Vehicle& Vehicle)。

由于

3 个答案:

答案 0 :(得分:1)

要获取声明的属性,请尝试使用BindingFlags.DeclaredOnly

以下是一个获取所有PublicInstanceDeclaredOnly属性的代码段。

PropertyInfo[] propertyInfos = objectToInspectType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);

绑定标志参考:http://msdn.microsoft.com/en-us/library/system.reflection.bindingflags(v=vs.110).aspx

根据您的示例类,这里是每种类型的结果。

typeof(Car):1个属性Color

typeof(Vehicle):1个属性WheelCount

tyepof(MyVehicles):2个属性vehicle1vehicle2

<强>更新

根据评论,您实际需要的是分配给该属性的值的Type。由于该属性为Vehicle,因此上述方法将返回typeof(Vehicle)。现在预计该属性将是Vehicle的类型。但是,当您将Car向下转换为Vehicle时,您需要检查该属性的值。

这可以在MarcinJuraszek给出的另一个答案之后完成,我已经将两个解决方案放在一起作为例子。

注意,如果值为null,那么属性类型将为Vehicle,因为它是其声明的类型。如果给出了该值,那么我们可以检查值的Type

这是一个只获得Declared属性的完整解决方案[I.E.不是从基类继承]。

static void Main(string[] args)
{
    MyVehicles vehicles = new MyVehicles();
    Type objectToInspectType = vehicles.GetType();
    PropertyInfo[] propertyInfos = objectToInspectType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
    foreach (PropertyInfo item in propertyInfos)
    {
        Type propertyType = item.PropertyType;
        object value = item.GetValue(vehicles, null);
        if (value != null)
            propertyType = value.GetType();
        Console.WriteLine(propertyType.Name); 
    }
    Console.ReadKey();
}

运行时,输出将为CarCar,因为属性vehicle1vehicle2的值设置为{{1}类型的值}}。神奇的事情发生在以下几行:

Car

我们将变量Type propertyType = item.PropertyType; object value = item.GetValue(vehicles, null); if (value != null) propertyType = value.GetType(); 声明为属性propertyType的类型,然后我们从行item.PropertyType行获取该属性的vehicles的值。如果设置了值(即不是object value = item.GetValue(vehicles, null);),那么我们使用null将变量propertyType设置为值的类型。

如果您要取消设置value.GetType()的值(设置为vehicle1),则上述方法返回的属性类型将为null

我希望这有帮助,如果您有任何其他问题,请与我联系。

答案 1 :(得分:0)

要获取分配给该属性且未声明属性类型的实际对象类型,请使用以下命令:

foreach (PropertyInfo item in propertyInfos)
{
    var value = item.GetValue(vehicles);
    var type = value == null ? item.PropertyType : value.GetType();
    Console.WriteLine(type.Name);
}

答案 2 :(得分:0)

更正后的版本

foreach (PropertyInfo item in propertyInfos)
        {
            Object value;

            if (item.GetIndexParameters().Length == 0)
            {
                value = item.GetValue(vehicles, null);
            }
            else
            {
                value = item.GetValue(vehicles, new object[] { 0 });  // string property is returned as a char array and consequently need index
            }

            Type  type = value == null ? item.PropertyType : value.GetType();
            Console.WriteLine(type.Name);
        }