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

C# 如何通过反射查找类型的非继承属性,c#,reflection,C#,Reflection,我想从特定类型中声明的类中检索属性,不包括从基类型继承的属性 当然这是一个简单的例子,但我想提取尽可能最简单的代码 实际情况要复杂一点,所以我真的不想改变方法 这是我的密码: class Program { static void Main(string[] args) { MyVehicles vehicles = new MyVehicles(); Type objectToInspectType = vehicles.GetType();

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

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

实际情况要复杂一点,所以我真的不想改变方法

这是我的密码:

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; }
}
我想要两个属性(车和车,而不是车和车)


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

下面是一个获取所有
Public
Instance
DeclaredOnly
属性的代码片段

PropertyInfo[] propertyInfos = objectToInspectType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
绑定标志引用:

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

typeof(Car)
:1属性
Color

类型(车辆)
:1属性
轮数

tyepof(MyVehicles)
:2属性
vehicle1
vehicle2

已更新

根据注释,您实际查找的是分配给属性的值的
类型。由于属性是
Vehicle
,上述方法将返回
typeof(Vehicle)
。现在,预计该属性将是一种
车辆
。但是,当您将
汽车
向下转换为
汽车
时,您需要检查属性的值

这可以根据MarcinJuraszek给出的另一个答案来完成,我将这两个解决方案放在一起作为示例

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

下面是一个完整的解决方案,它只获取
声明的
属性[即,不从基类继承]

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();
}
运行时,输出将为
Car
Car
,因为属性
vehicle1
vehicle2
的值设置为
Car
类型的值。神奇之处在于:

Type propertyType = item.PropertyType;
object value = item.GetValue(vehicles, null);
if (value != null)
    propertyType = value.GetType();
在这里,我们将变量
propertyType
声明为属性
项的类型。propertyType
,接下来我们从
车辆
中获取该属性的值,行
对象值=项.GetValue(车辆,null)。如果设置了值(即非
null
),则我们使用
value.GetType()
将变量
propertyType
设置为值的类型

如果要取消设置
vehicle1
(将其设置为
null
),则上述方法返回的属性类型将为
Vehicle


我希望这会有所帮助,如果您还有其他问题,请告诉我。

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

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

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);
        }

感谢您的回答,但我不想显示Car&Car,而不是车辆&Vehicle,如:PropertyInfo[]propertyInfos=objectToInspectType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);好的,我已经根据你的评论更新了我的答案。。干杯。谢谢。这对我有帮助。只是稍微修改一下。