如何检查的编译器的属性名称/表达式树传递给自定义属性 [英] How to pass compiler checked property names / Expression tree to a custom attribute

查看:104
本文介绍了如何检查的编译器的属性名称/表达式树传递给自定义属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一些地方,我注意到作为参数传递给方法,使属性名称的编译器检查表达式树。例如,卡利科技在其PropertyChangedBase类下面的方法签名:

 公共虚拟无效NotifyOfPropertyChange< TProperty>(表达式来;函数功能:LT ; TProperty>>财产); 



我有我想有相同类型的属性名的编译器检查的自定义属性构造,使我能够键入:

  [MyCustomAttribute(()=>属性名)

而不是:

  [MyCustomAttribute(属性名)] 

使用构造函数的定义大致为:

 公共MyCustomAttribute(PARAMS表达式来; Func键<对象>> []属性)

然而,由于对属性参数是常量表达式的限制,这似乎不是可能的。



?谁能推荐一个不同的方法,我可以让编译器在我的属性参数来检查属性的名称,而不是留在那里只使用字符串这种潜在的bug。



编辑:感谢马克的回答,我已经实现了这个现在:

 #如果DEBUG 
的foreach(VAR的PropertyInfo在
的GetType()的GetProperties(),其中(的PropertyInfo =过夜。; Attribute.IsDefined(的PropertyInfo的typeof(MyCustomAttribute))))
{
的foreach(在propertyInfo.GetAttributes< VAR propertyName的; MyCustomAttribute>(真)
.SelectMany(属性=> attribute.PropertyNames ))
Debug.Assert的(
的GetType()。的getProperty(propertyName的)!= NULL,
找不到属性,
物权宣布由于房地产{0} { 。1}的类型{2},
propertyName的,propertyInfo.Name,的GetType()名称
)未找到;
}
#ENDIF


解决方案

这简直是​​不可能的。属性限于非常基本类型不包含则需要什么此。其中的可能的做这件事的静态安全的方法是将继承每财产属性的但这是工作的一个疯狂的金额。



就个人而言,我只是写一个单元测试,找到属性,并检查它们是通过反射明智的所有地方。你也可以这样做在#如果DEBUG 块(或类似)内的主代码。


In a few places, I've noticed expression trees passed as arguments to methods to allow compiler checking of property names. For example, Caliburn Micro has the following method signature in its PropertyChangedBase class:

public virtual void NotifyOfPropertyChange<TProperty>(Expression<Func<TProperty>> property);

I have a custom attribute which I would like to have the same type of compiler checking of property names in the constructor, to enable me to type:

[MyCustomAttribute(() => PropertyName)]

Instead of:

[MyCustomAttribute("PropertyName")]

Using a constructor definition along the lines of:

public MyCustomAttribute(params Expression<Func<object>>[] properties)

However, due to the restriction on Attribute parameters being constant expressions, this appears not to be possible.

Can anyone recommend a different approach where I can get the compiler to check property names in my attribute parameters rather than leaving this potential bug where only strings are used?

Edit: Thanks to Marc's answer, I have implemented this for now:

#if DEBUG
            foreach (var propertyInfo in
                GetType().GetProperties().Where(propertyInfo => Attribute.IsDefined(propertyInfo, typeof (MyCustomAttribute))))
            {
                foreach (var propertyName in propertyInfo.GetAttributes<MyCustomAttribute>(true)
                    .SelectMany(attribute => attribute.PropertyNames))
                    Debug.Assert(
                        GetType().GetProperty(propertyName) != null,
                        "Property not found",
                        "Property {0} declared on attributed property {1} was not found on type {2}.",
                        propertyName, propertyInfo.Name, GetType().Name
                    );
            }
#endif

解决方案

This is simply not possible. Attributes are limited to very basic types that don't include what you would need for this. One possible static-safe way of doing it would be to subclass the attribute per property but that is an insane amount of work.

Personally, I'd just write a unit test that finds all occurrences of the attribute and checks they are sensible via reflection. You could also do this in the main code inside a #if DEBUG block (or similar).

这篇关于如何检查的编译器的属性名称/表达式树传递给自定义属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆