2

プロパティとそれに関連する属性をコレクションまたはプロパティ セットとして取得することはできますか?

私が見ているオブジェクトのプロパティには、JSON.NET で使用するための属性があり、それらがすべて何であるかを調べたいと思います。その後、null でないものを見つけようとします。

サンプル オブジェクトは次のとおりです。

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

4 に答える 4

5

これにより、すべてのプロパティ、それらの属性、および属性の引数の値が得られます(このソリューションでは、.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
于 2013-03-21T03:48:38.740 に答える
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;
    }
于 2013-03-21T02:56:00.553 に答える
2

上記のChrisの回答と、この質問に対するMarc Gravellの回答を読んだ後、私は答えを見つけました

私はそれを行うためにこの関数を作成しました:

    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;
    }
于 2013-03-21T03:39:31.010 に答える
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表示されないことに注意してください。

于 2013-03-21T03:17:56.413 に答える