2014-01-22 37 views
0

我想从特定类型中声明的类中检索属性,但不包括从基类型继承的类。如何通过反射查找类型的非继承属性

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

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

这里是我的代码:

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

我想两个属性(汽车&汽车,而不是汽车&车辆)。

感谢

回答

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

更新

根据你实际上是在寻找的评论是分配给财产的价值。由于该物业是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的值被设置为类型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),则我们使用value.GetType()将变量propertyType设置为值的类型。

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

我希望这可以帮助,让我知道如果你有任何其他问题。

+0

感谢您的回答,但我wan't什么是显示汽车和汽车,而不是车辆和车辆是这种情况:PropertyInfo [] propertyInfos = objectToInspectType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public); – DominiqueRT

+0

好吧,我根据你的意见更新了我的答案。干杯。 – Nico

0

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

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

谢谢它帮助我。只需修改一下。 – DominiqueRT

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