Пользовательский атрибут свойства - Тип и значение атрибута атрибута
У меня есть следующий настраиваемый атрибут, который можно применить к свойствам:
[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 и т.д.) И фактическое значение, очевидно, основанное на типе.
Ответы
Ответ 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;
}