我可以将自定义属性限制为仅无效方法吗?
Can I restrict a custom attribute to void methods only?
我有一个自定义属性,我想将其限制为 return 类型为 void 的方法。
我知道我可以限制使用 [AttributeUsage(AttributeTargets.Method)]
的方法,但似乎没有办法限制 return 类型或方法签名的任何其他方面。
[System.Diagnostics.Conditional]
属性正是我想要的那种限制。将其添加到非 void 方法会导致编译器错误:
The Conditional attribute is not valid on '(SomeMethod)' because its return type is not void
并且 IntelliSense 说:
Attribute 'System.Diagnostics.ConditionalAttribute' is only valid on
attribute classes or methods with 'void' return type.
如果我 F12 到 ConditionalAttribute
我看到它装饰有以下属性:
[Serializable]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
[ComVisible(true)]
None 其中提到了 return 类型。
Conditional
属性是如何完成的?我可以为我的自定义属性做同样的事情吗?
大多数属性只是附加到 classes 的元数据,可以在 运行 时检查。但是,编译器会使用一些属性。 System.ObsoleteAttribute
例如,如果使用 class 等方法,可用于让编译器发出错误或警告。 System.Diagnostics.ConditionalAttribute
是编译器使用的属性的另一个示例。因此,编译器本身可以自由地对其使用施加规则,这些规则不能应用于其他属性(例如仅限 void 方法)。
遗憾的是,目前无法通过自定义属性影响编译器。由于 Rosalyn 是用 C# 编写的,因此打开了将属性中的编译器 运行 代码作为编译阶段的一部分的方式。您将属性限制为 void 方法的示例将是此功能的一种此类用途,如果它已实现的话。
在我的特殊情况下,因为我使用的是 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;
}
我有一个自定义属性,我想将其限制为 return 类型为 void 的方法。
我知道我可以限制使用 [AttributeUsage(AttributeTargets.Method)]
的方法,但似乎没有办法限制 return 类型或方法签名的任何其他方面。
[System.Diagnostics.Conditional]
属性正是我想要的那种限制。将其添加到非 void 方法会导致编译器错误:
The Conditional attribute is not valid on '(SomeMethod)' because its return type is not void
并且 IntelliSense 说:
Attribute 'System.Diagnostics.ConditionalAttribute' is only valid on attribute classes or methods with 'void' return type.
如果我 F12 到 ConditionalAttribute
我看到它装饰有以下属性:
[Serializable]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
[ComVisible(true)]
None 其中提到了 return 类型。
Conditional
属性是如何完成的?我可以为我的自定义属性做同样的事情吗?
大多数属性只是附加到 classes 的元数据,可以在 运行 时检查。但是,编译器会使用一些属性。 System.ObsoleteAttribute
例如,如果使用 class 等方法,可用于让编译器发出错误或警告。 System.Diagnostics.ConditionalAttribute
是编译器使用的属性的另一个示例。因此,编译器本身可以自由地对其使用施加规则,这些规则不能应用于其他属性(例如仅限 void 方法)。
遗憾的是,目前无法通过自定义属性影响编译器。由于 Rosalyn 是用 C# 编写的,因此打开了将属性中的编译器 运行 代码作为编译阶段的一部分的方式。您将属性限制为 void 方法的示例将是此功能的一种此类用途,如果它已实现的话。
在我的特殊情况下,因为我使用的是 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;
}