Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 检查属性是否具有属性_C#_Performance - Fatal编程技术网

C# 检查属性是否具有属性

C# 检查属性是否具有属性,c#,performance,C#,Performance,给定类中的一个属性和属性-确定它是否包含给定属性的最快方法是什么?例如: [IsNotNullable] [IsPK] [IsIdentity] [SequenceNameAttribute("Id")] public Int32 Id { get { return _Id; } set { _Id = value;

给定类中的一个属性和属性-确定它是否包含给定属性的最快方法是什么?例如:

    [IsNotNullable]
    [IsPK]
    [IsIdentity]
    [SequenceNameAttribute("Id")]
    public Int32 Id
    {
        get
        {
            return _Id;
        }
        set
        {
            _Id = value;
        }
    }

确定它是否具有“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
}

如果您使用的是.NET3.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;
    }
}
类CustomAttribute:属性{}
班级计划
{
[海关]
公共int Id{get;set;}
静态void Main()
{
Expression=p=>p.Id;
var memberExpression=(memberExpression)expression.Body;
bool hasCustomAttribute=memberExpression
.成员
.GetCustomAttributes(typeof(CustomAttribute),false)。长度>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;
            }
public static bool TryGetAttribute(MemberInfo MemberInfo,out T customAttribute),其中T:Attribute{
var attributes=memberInfo.GetCustomAttributes(typeof(T),false).FirstOrDefault();
如果(属性==null){
customAttribute=null;
返回false;
}
customAttribute=(T)属性;
返回true;
}

要更新和/或增强@Hans Passant的答案,我将把属性的检索分离为一个扩展方法。这还有一个额外的好处,就是删除方法GetProperty()中令人讨厌的魔术字符串

公共静态类属性帮助器
{
公共静态属性info GetProperty(
表达式选择器)
{
表达式体=选择器;
if(主体为LambdaExpression)
{
body=((LambdaExpression)body.body;
}
开关(body.NodeType)
{
case ExpressionType.MemberAccess:
返回(PropertyInfo)((MemberExpression)body.Member;
违约:
抛出新的InvalidOperationException();
}
}
}
然后,您的测试将减少到两行

var property = PropertyHelper<MyClass>.GetProperty(x => x.MyProperty);
Attribute.IsDefined(property, typeof(MyPropertyAttribute));
var-property=PropertyHelper.GetProperty(x=>x.MyProperty);
属性.IsDefined(property,typeof(MyPropertyAttribute));

如果您正试图在可移植类库PCL(像我一样)中实现这一点,那么以下是您可以实现的方法:)

公共类Foo
{
公共字符串A{get;set;}
[特别]
公共字符串B{get;set;}
}
变量类型=类型(Foo);
var specialProperties=type.GetRuntimeProperties()
.Where(pi=>pi.PropertyType==typeof(字符串)
&&GetCustomAttributes(true.Any());

然后,如果需要,可以检查具有此特殊属性的属性数

这是一个很老的问题,但我用了

我的方法具有此参数,但可以构建:

Expression<Func<TModel, TValue>> expression

使用新的C#功能
nameof()

Attribute.IsDefined(typeof(YourClass).GetProperty(nameof(YourClass.Id)), typeof(IsIdentity));

是在C#6中引入的,您可以使用Attribute.IsDefined方法

您可以提供您特别寻找的属性,也可以使用反射对所有属性进行迭代,例如:

PropertyInfo[] props = typeof(YourClass).GetProperties();

如果您只需要检查属性是否存在,而不从中检索任何信息,请使用
属性。IsDefined
将消除一行代码和难看的数组/类型转换。我刚才遇到的问题是,某些属性的属性名有不同的类型。例如,System.ComponentModel.DataAnnotations.Schema中的“NotMapped”在类中用作
[NotMapped]
,但要检测它,必须使用
属性。IsDefined(pi,typeof(NotMappeAttribute))
可能更容易使用泛型重载:
IsIdentity[]attr=pi.GetCustomAttributes(false)
@Qjimbo(或者可能是其他正在阅读的人)属性通常不使用其名称中的“属性”部分,但可以是。约定允许您将其排除在外,因此通常实际类型的名称末尾有属性,但不使用。仅供参考,有人询问了您的答案。这不能编译。您不能在属性或属性周围使用[]。前面的每个答案都使用了我所遵循的类、属性和属性名称的假设。现在看来已修复。
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(typeof(YourClass).GetProperty(nameof(YourClass.Id)), typeof(IsIdentity));
if(Attribute.IsDefined(YourProperty,typeof(YourAttribute)))
{
    //Conditional execution...
}
PropertyInfo[] props = typeof(YourClass).GetProperties();