web-dev-qa-db-fra.com

Attribut personnalisé sur la propriété - Obtention du type et de la valeur de la propriété attribuée

J'ai l'attribut personnalisé suivant, qui peut être appliqué sur les propriétés:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class IdentifierAttribute : Attribute
{
}

Par exemple:

public class MyClass
{
    [Identifier()]
    public string Name { get; set; }

    public int SomeNumber { get; set; }
    public string SomeOtherProperty { get; set; }
}

Il y aura également d'autres classes, auxquelles l'attribut Identifier pourrait être ajouté à des propriétés de type différent:

public class MyOtherClass
{
    public string Name { get; set; }

    [Identifier()]
    public int SomeNumber { get; set; }

    public string SomeOtherProperty { get; set; }
}

Je dois ensuite être en mesure d'obtenir ces informations dans ma classe consommatrice. Par exemple:

public class TestClass<T>
{
    public void GetIDForPassedInObject(T obj)
    {
        var type = obj.GetType();
        //type.GetCustomAttributes(true)???
    }
}

Quelle est la meilleure façon de procéder? J'ai besoin d'obtenir le type du champ [Identifier ()] (int, chaîne, etc ...) et la valeur réelle, évidemment basée sur le type.

29
Alex

Quelque chose comme le suivant, cela n'utilisera que la première propriété rencontrée qui a l'attribut, bien sûr, vous pouvez le placer sur plusieurs.

    public object GetIDForPassedInObject(T obj)
    {
        var prop = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)
                   .FirstOrDefault(p => p.GetCustomAttributes(typeof(IdentifierAttribute), false).Count() ==1);
        object ret = prop !=null ?  prop.GetValue(obj, null) : null;

        return ret;
    }  
38
Richard Friend

Un peu en retard, mais voici quelque chose que j'ai fait pour les énumérations (cela pourrait être n'importe quel objet également) et obtenir la valeur de l'attribut de description en utilisant une extension (cela pourrait être un générique pour n'importe quel attribut):

public enum TransactionTypeEnum
{
    [Description("Text here!")]
    DROP = 1,

    [Description("More text here!")]
    PICKUP = 2,

    ...
}

Obtenir la valeur:

var code = TransactionTypeEnum.DROP.ToCode();

Extension prenant en charge toutes mes énumérations:

public static string ToCode(this TransactionTypeEnum val)
{
    return GetCode(val);
}

public static string ToCode(this DockStatusEnum val)
{
    return GetCode(val);
}

public static string ToCode(this TrailerStatusEnum val)
{
    return GetCode(val);
}

public static string ToCode(this DockTrailerStatusEnum val)
{
    return GetCode(val);
}

public static string ToCode(this EncodingType val)
{
    return GetCode(val);
}

private static string GetCode(object val)
{
    var attributes = (DescriptionAttribute[])val.GetType().GetField(val.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);

    return attributes.Length > 0 ? attributes[0].Description : string.Empty;
}
2
PmanAce
public class TestClass<T>
{
    public void GetIDForPassedInObject(T obj)
    {
        PropertyInfo[] properties =
            obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);            

        PropertyInfo IdProperty = (from PropertyInfo property in properties
                           where property.GetCustomAttributes(typeof(Identifier), true).Length > 0
                           select property).First();

         if(null == IdProperty)
             throw new ArgumentException("obj does not have Identifier.");

         Object propValue = IdProperty.GetValue(entity, null)
    }
}
2