c# - 如何将编译器检查的属性名称/表达式树传递给自定义属性

标签 c# expression-trees custom-attributes

在一些地方,我注意到表达式树作为参数传递给方法以允许编译器检查属性名称。例如,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/

相关文章:

C# 变量 getter / setter

c# - 解析 Json 返回字符串还是字符串数组?

.net - LINQ 表达式 TreeMap 灵完整吗?

android - 如何在属性集中获取对另一个 View 的引用 - 类似于相对布局中的 layout_below = "id"?

c# - 使用字符串实现自定义 IComparer

c# - 策略模式与多态有何不同?

linq - IronPython 的表达式树

c# - .NET 中的表达式树 - 库?

asp.net-mvc - 修剪除具有 NoTrim 属性的输入字段之外的所有输入字段

c# - 我应该为枚举成员使用什么 AttributeTarget?