我有一个自定义属性,我想将其限制为返回类型为void的方法。
我知道我可以限制使用[AttributeUsage(AttributeTargets.Method)]
的方法,但似乎没有办法限制返回类型或方法签名的任何其他方面。
[System.Diagnostics.Conditional]
属性正是我想要的那种限制。将其添加到非void方法会导致编译器错误:
Conditional属性在'(SomeMethod)'上无效,因为它的返回类型不是空的
和IntelliSense说:
属性'System.Diagnostics.ConditionalAttribute'仅对有效 具有'void'返回类型的属性类或方法。
如果我F12到ConditionalAttribute
我看到它装饰有以下属性:
[序列化]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,AllowMultiple = true)]
[标记有ComVisible特性(真)]
其中没有任何关于返回类型的内容。
如何为Conditional
属性完成,我可以为自定义属性执行相同操作吗?
答案 0 :(得分:4)
在我的特定情况下,由于我使用的是PostSharp,因此有一个解决方案。
我的自定义属性继承自PostSharp.Aspects.MethodInterceptionAspect
(继承自Attribute
),具有可覆盖的CompileTimeValidate(MethodBase method)
方法。
这允许在构建期间发出编译器错误:
public override bool CompileTimeValidate(MethodBase method)
{
Debug.Assert(method is MethodInfo);
var methodInfo = (MethodInfo)method;
if (methodInfo.ReturnType != typeof(void))
{
Message.Write(
method, SeverityType.Error, "CX0001",
"The Foo attribute is not valid on '{0}' because its return type is not void",
method.Name);
return false;
}
return true;
}
答案 1 :(得分:3)
大多数属性只是附加到类的元数据,可以在运行时检查。但是,编译器使用某些属性。例如,System.ObsoleteAttribute
可用于让编译器在使用方法,类等时发出错误或警告。 System.Diagnostics.ConditionalAttribute
是编译器使用的属性的另一个示例。因此,编译器本身可以自由地对其使用施加规则,这些规则不能应用于其他属性(例如仅使用void方法)。
不幸的是,目前,通过自定义属性不可能影响编译器。随着Rosalyn用C#编写,然后打开方式让编译器在属性中运行代码作为编译阶段的一部分。如果实现了限制属性为void方法,则可以使用此功能。