在一些地方,我注意到表达式树作为参数传递给方法以允许编译器检查属性名称。例如,Caliburn Micro 在其 PropertyChangedBase 类中具有以下方法签名:
public virtual void NotifyOfPropertyChange<TProperty>(Expression<Func<TProperty>> property);
我有一个自定义属性,我希望在构造函数中有相同类型的编译器检查属性名称,以使我能够键入:
[MyCustomAttribute(() => PropertyName)]
代替:
[MyCustomAttribute("PropertyName")]
按照以下行使用构造函数定义:
public MyCustomAttribute(params Expression<Func<object>>[] properties)
但是,由于属性参数是常量表达式的限制,这似乎是不可能的。
谁能推荐一种不同的方法,让编译器检查我的属性参数中的属性名称,而不是在只使用字符串的地方留下这个潜在的错误?
编辑:感谢 Marc 的回答,我现在已经实现了这个:
#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
最佳答案
这根本不可能。属性仅限于非常基本的类型,不包括您为此所需的内容。一种可能静态安全的方法是将属性每个属性 子类化,但这是一项疯狂的工作量。
就个人而言,我只是编写一个单元测试来查找所有出现的属性并通过反射检查它们是否合理。您也可以在 #if DEBUG
block (或类似 block )内的主代码中执行此操作。
关于c# - 如何将编译器检查的属性名称/表达式树传递给自定义属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4518291/