Проверьте, имеет ли свойство атрибут
Учитывая свойство в классе, с атрибутами - какой самый быстрый способ определить, содержит ли он данный атрибут? Например:
[IsNotNullable]
[IsPK]
[IsIdentity]
[SequenceNameAttribute("Id")]
public Int32 Id
{
get
{
return _Id;
}
set
{
_Id = value;
}
}
Каков самый быстрый способ определить, что, например, он имеет атрибут IsIdentity?
Ответы
Ответ 1
Нет быстрого способа получить атрибуты. Но код должен выглядеть так (кредит Aaronaught):
var t = typeof(YourClass);
var pi = t.GetProperty("Id");
var hasIsIdentity = Attribute.IsDefined(pi, typeof(IsIdentity));
Если вам нужно получить свойства атрибута, то
var t = typeof(YourClass);
var pi = t.GetProperty("Id");
var attr = (IsIdentity[])pi.GetCustomAttributes(typeof(IsIdentity), false);
if (attr.Length > 0) {
// Use attr[0], you'll need foreach on attr if MultiUse is true
}
Ответ 2
Если вы используете .NET 3.5, вы можете попробовать с помощью деревьев выражений. Это безопаснее, чем отражение:
class CustomAttribute : Attribute { }
class Program
{
[Custom]
public int Id { get; set; }
static void Main()
{
Expression<Func<Program, int>> expression = p => p.Id;
var memberExpression = (MemberExpression)expression.Body;
bool hasCustomAttribute = memberExpression
.Member
.GetCustomAttributes(typeof(CustomAttribute), false).Length > 0;
}
}
Ответ 3
Вы можете использовать общий (общий) метод для чтения атрибута над данным MemberInfo
public static bool TryGetAttribute<T>(MemberInfo memberInfo, out T customAttribute) where T: Attribute {
var attributes = memberInfo.GetCustomAttributes(typeof(T), false).FirstOrDefault();
if (attributes == null) {
customAttribute = null;
return false;
}
customAttribute = (T)attributes;
return true;
}
Ответ 4
Если вы пытаетесь сделать это в PCL портативной библиотеки классов (например, я), то вот как вы можете это сделать:)
public class Foo
{
public string A {get;set;}
[Special]
public string B {get;set;}
}
var type = typeof(Foo);
var specialProperties = type.GetRuntimeProperties()
.Where(pi => pi.PropertyType == typeof (string)
&& pi.GetCustomAttributes<Special>(true).Any());
Затем вы можете проверить количество свойств, имеющих это специальное свойство, если вам нужно.
Ответ 5
Чтобы обновить и/или улучшить ответ от @Hans Passant, я хотел бы отделить извлечение свойства в метод расширения. Это имеет дополнительное преимущество для удаления неприятной магической строки в методе GetProperty()
public static class PropertyHelper<T>
{
public static PropertyInfo GetProperty<TValue>(
Expression<Func<T, TValue>> selector)
{
Expression body = selector;
if (body is LambdaExpression)
{
body = ((LambdaExpression)body).Body;
}
switch (body.NodeType)
{
case ExpressionType.MemberAccess:
return (PropertyInfo)((MemberExpression)body).Member;
default:
throw new InvalidOperationException();
}
}
}
Затем ваш тест сводится к двум строкам
var property = PropertyHelper<MyClass>.GetProperty(x => x.MyProperty);
Attribute.IsDefined(property, typeof(MyPropertyAttribute));
Ответ 6
Это довольно старый вопрос, но я использовал
Мой метод имеет этот параметр, но он может быть построен:
Expression<Func<TModel, TValue>> expression
Тогда в методе this:
System.Linq.Expressions.MemberExpression memberExpression
= expression.Body as System.Linq.Expressions.MemberExpression;
Boolean hasIdentityAttr = System.Attribute
.IsDefined(memberExpression.Member, typeof(IsIdentity));