回答:
属性をすばやく取得する方法はありません。しかし、コードは次のようにする必要があります(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
}
[NotMapped]
クラスではなく、それはあなたが使用する必要が検出するAttribute.IsDefined(pi, typeof(NotMappedAttribute))
IsIdentity[] attr = pi.GetCustomAttributes<IsIdentity>(false);
.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;
}
}
共通(汎用)メソッドを使用して、特定の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;
}
@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();
}
}
}
テストは2行に削減されます
var property = PropertyHelper<MyClass>.GetProperty(x => x.MyProperty);
Attribute.IsDefined(property, typeof(MyPropertyAttribute));
(私のような)ポータブルクラスライブラリ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());
その後、必要に応じて、この特別なプロパティを持つプロパティの数を確認できます。
Attribute.IsDefinedメソッドを使用できます
https://msdn.microsoft.com/en-us/library/system.attribute.isdefined(v=vs.110).aspx
if(Attribute.IsDefined(YourProperty,typeof(YourAttribute)))
{
//Conditional execution...
}
具体的に探しているプロパティを提供したり、次のようなリフレクションを使用してすべてのプロパティを反復処理したりできます。
PropertyInfo[] props = typeof(YourClass).GetProperties();
これはかなり古い質問ですが、私は
私のメソッドにはこのパラメーターがありますが、構築することができます:
Expression<Func<TModel, TValue>> expression
次に、メソッドでこれ:
System.Linq.Expressions.MemberExpression memberExpression
= expression.Body as System.Linq.Expressions.MemberExpression;
Boolean hasIdentityAttr = System.Attribute
.IsDefined(memberExpression.Member, typeof(IsIdentity));
Attribute.IsDefined
すると、1行のコードと醜い配列/キャストを削除できます。