2013-03-21 121 views
0

是否可以将属性及其关联属性作为集合或属性集?是否可以获取对象的属性和关联属性?

我正在查看的对象的属性具有在JSON.NET中使用的属性,我想知道它们是什么。之后,我会试着找出其中哪些不是空的。

这里有一个样本对象:

[JsonObject] 
    public class Conditions 
    { 
     [JsonProperty("opened_since")] 
     public DateTime? OpenedSince { get; set; } 
     [JsonProperty("added_until")] 
     public DateTime? AddedUntil { get; set; } 
     [JsonProperty("opened_until")] 
     public DateTime? OpenedUntil { get; set; } 
     [JsonProperty("archived_until")] 
     public DateTime? ArchivedUntil { get; set; 
    } 
+0

你的意思是像'条件c; PropertiesInfo infos = c.GetType()。GetProperties();'? – Fendy 2013-03-21 02:54:38

回答

3

这会给你的所有属性,其属性和(请注意,此解决方案假定您使用的是.NET Framework版本4.5):

PropertyInfo[] props = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); 
foreach (PropertyInfo prop in props) 
{ 
    Console.WriteLine("Property: " + prop.Name); 
    foreach (CustomAttributeData att in prop.CustomAttributes) 
    { 
     Console.WriteLine("\tAttribute: " + att.AttributeType.Name); 
     foreach (CustomAttributeTypedArgument arg in att.ConstructorArguments) 
     { 
      Console.WriteLine("\t\t" + arg.ArgumentType.Name + ": " + arg.Value); 
     } 
    } 
} 

输出:

Property: OpenedSince 
     Attribute: JsonPropertyAttribute 
       String: opened_since 
Property: AddedUntil 
     Attribute: JsonPropertyAttribute 
       String: added_until 
Property: OpenedUntil 
     Attribute: JsonPropertyAttribute 
       String: opened_until 
Property: ArchivedUntil 
     Attribute: JsonPropertyAttribute 
       String: archived_until 
+0

Fyi,如果属性设置像[JsonProperty(PropertyName =“opened_since”],我们必须使用NamedArguements而不是att.ConstructorArguments – justcoding124 2015-08-17 19:49:17

2

试试这个

public static Hashtable ConvertPropertiesAndValuesToHashtable(this object obj) 
    { 
     var ht = new Hashtable(); 

     // get all public static properties of obj type 
     PropertyInfo[] propertyInfos = 
      obj.GetType().GetProperties().Where(a => a.MemberType.Equals(MemberTypes.Property)).ToArray(); 
     // sort properties by name 
     Array.Sort(propertyInfos, (propertyInfo1, propertyInfo2) => propertyInfo1.Name.CompareTo(propertyInfo2.Name)); 

     // write property names 
     foreach (PropertyInfo propertyInfo in propertyInfos) 
     { 
      ht.Add(propertyInfo.Name, 
        propertyInfo.GetValue(obj, BindingFlags.Public, null, null, CultureInfo.CurrentCulture)); 
     } 

     return ht; 
    } 
+0

谢谢,但这并没有得到属性的属性。 – chustar 2013-03-21 03:03:31

1

像这样的事情?如果我理解正确,您需要该类由属性修饰的所有属性。我不想包含JSON.NET参考,因此改用XmlText属性。

[Test] 
    public void dummy() 
    { 
     var conditions = new Conditions(); 

     var propertyInfos = conditions.GetType().GetProperties(); 
     propertyInfos.ForEach(x => 
      { 
       var attrs = x.GetCustomAttributes(true); 
       if (attrs.Any(p => p.GetType() == typeof(XmlTextAttribute))) 
       { 
        Console.WriteLine("{0} {1}", x, attrs.Aggregate((o, o1) => string.Format("{0},{1}",o,o1))); 
       } 
      }); 
    } 

和类看起来是这样的 -

[XmlType] 
public class Conditions 
{ 
    [XmlText] 
    public DateTime? OpenedSince { get; set; } 

    [XmlText] 
    public DateTime? AddedUntil { get; set; } 

    [XmlText] 
    public DateTime? OpenedUntil { get; set; } 

    [XmlText] 
    public DateTime? ArchivedUntil { get; set; } 

    public string NotTobeListed { get; set; } 
} 

控制台输出:

System.Nullable`1[System.DateTime] OpenedSince System.Xml.Serialization.XmlTextAttribute 
System.Nullable`1[System.DateTime] AddedUntil System.Xml.Serialization.XmlTextAttribute 
System.Nullable`1[System.DateTime] OpenedUntil System.Xml.Serialization.XmlTextAttribute 
System.Nullable`1[System.DateTime] ArchivedUntil System.Xml.Serialization.XmlTextAttribute 

注意NotToBeListed不显示。

+0

谢谢但不显示属性。 – chustar 2013-03-21 03:36:04

+0

这应该不是太难,已经用一种方式更新了我的答案。可以做一些重构。 – 2013-03-21 04:07:16

2

我想出答案阅读上述和Marc Gravell's answer to this question

克里斯的回答后,我创造了这个功能做到这一点对我来说:

public HastTable BuildRequestFromConditions(Conditions conditions) 
    { 
     var ht = new HashTable(); 
     var properties = conditions.GetType().GetProperties().Where(a => a.MemberType.Equals(MemberTypes.Property) && a.GetValue(conditions) != null); 
     properties.ForEach(property => 
      { 
       var attribute = property.GetCustomAttribute(typeof(JsonPropertyAttribute)); 
       var castAttribute = (JsonPropertyAttribute)attribute; 

       ht.Add(castAttribute.PropertyName, property.GetValue(conditions)); 
      }); 
     return request; 
    }