Подтвердить что ты не робот

Пользовательский атрибут свойства - Тип и значение атрибута атрибута

У меня есть следующий настраиваемый атрибут, который можно применить к свойствам:

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

Например:

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

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

Будут также другие классы, к которым атрибут Идентификатор может быть добавлен к свойствам другого типа:

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

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

    public string SomeOtherProperty { get; set; }
}

Затем мне нужно получить эту информацию в моем классе-потребителе. Например:

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

Какой лучший способ сделать это? Мне нужно получить тип поля [Идентификатор()] (int, string и т.д.) И фактическое значение, очевидно, основанное на типе.

4b9b3361

Ответ 1

Что-то вроде следующего: это будет использовать только первое свойство, которое оно набирает, которое имеет атрибут, конечно, вы можете разместить его более чем на одном.

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

Ответ 2

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

Ответ 3

Немного поздно, но я кое-что сделал для перечислений (это может быть также любой объект) и получения значения атрибута описания с использованием расширения (это может быть универсальным для любого атрибута):

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

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

    ...
}

Получение значения:

var code = TransactionTypeEnum.DROP.ToCode();

Расширение, поддерживающее все мои перечисления:

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