Otá*_*cio 152 c# performance
给定类中的属性,使用属性 - 确定它是否包含给定属性的最快方法是什么?例如:
[IsNotNullable]
[IsPK]
[IsIdentity]
[SequenceNameAttribute("Id")]
public Int32 Id
{
get
{
return _Id;
}
set
{
_Id = value;
}
}
Run Code Online (Sandbox Code Playgroud)
确定例如它具有"IsIdentity"属性的最快方法是什么?
Han*_*ant 260
没有快速的方法来检索属性.但代码应该看起来像这样(归功于Aaronaught):
var t = typeof(YourClass);
var pi = t.GetProperty("Id");
var hasIsIdentity = Attribute.IsDefined(pi, typeof(IsIdentity));
Run Code Online (Sandbox Code Playgroud)
如果您需要检索属性属性
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
}
Run Code Online (Sandbox Code Playgroud)
Dar*_*rov 43
如果您使用的是.NET 3.5,则可以尝试使用Expression树.它比反思更安全:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
Man*_*ani 12
您可以使用公共(通用)方法读取给定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;
}
Run Code Online (Sandbox Code Playgroud)
Jim*_*lff 12
现在可以使用新的 C# 功能以类型安全的方式在没有表达式树和扩展方法的情况下完成此操作,nameof()
如下所示:
Attribute.IsDefined(typeof(YourClass).GetProperty(nameof(YourClass.Id)), typeof(IsIdentity));
Run Code Online (Sandbox Code Playgroud)
nameof()是在 C# 6 中引入的
您可以使用 Attribute.IsDefined 方法
https://msdn.microsoft.com/en-us/library/system.attribute.isdefined(v=vs.110).aspx
if(Attribute.IsDefined(YourProperty,typeof(YourAttribute)))
{
//Conditional execution...
}
Run Code Online (Sandbox Code Playgroud)
您可以提供您专门寻找的属性,也可以使用反射遍历所有属性,例如:
PropertyInfo[] props = typeof(YourClass).GetProperties();
Run Code Online (Sandbox Code Playgroud)
小智 7
要通过@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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后你的测试减少到两行
var property = PropertyHelper<MyClass>.GetProperty(x => x.MyProperty);
Attribute.IsDefined(property, typeof(MyPropertyAttribute));
Run Code Online (Sandbox Code Playgroud)
如果你想在便携式类库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());
Run Code Online (Sandbox Code Playgroud)
如果需要,您可以检查具有此特殊属性的属性数.