好的,这是我上一个问题的后续。
我真正想做的是创建某种属性,它允许我装饰一个会破坏 build的方法。很像Obsolete("reason", true)属性,但不会错误地识别过时的代码。
澄清一下:我不希望它在任何F6(构建)按下时破坏构建,我只希望它在代码中的其他位置调用带有属性的方法时破坏构建。就像我说的,类似于过时,但不一样。
我知道我并不孤单,因为其他用户出于其他原因想要使用它。我以前从未创建过自定义属性,所以这对我来说是全新的!
好的,这是我上一个问题的后续。
我真正想做的是创建某种属性,它允许我装饰一个会破坏 build的方法。很像Obsolete("reason", true)属性,但不会错误地识别过时的代码。
澄清一下:我不希望它在任何F6(构建)按下时破坏构建,我只希望它在代码中的其他位置调用带有属性的方法时破坏构建。就像我说的,类似于过时,但不一样。
我知道我并不孤单,因为其他用户出于其他原因想要使用它。我以前从未创建过自定义属性,所以这对我来说是全新的!
我认为这对微软来说是一个很好的功能要求:创建一个抽象基类属性CompilerExecutedAttribute
,编译器以某种方式处理或影响编译过程。然后我们可以继承这个属性并实现不同的操作,例如发出错误或警告。
如果这是用于 XML 序列化和 NHibernate,您希望无参数构造函数可访问(如您引用的示例中的情况),则使用私有或受保护的无参数构造函数进行序列化,或 NHibernate 的受保护构造函数。使用受保护的版本,您可以向能够调用该代码的继承类敞开大门。
如果您不希望代码调用方法,请不要使其可访问。
编辑:为了回答更深层次的问题,AFAIK 编译器只知道三个属性:Obsolete、Conditional 和 AttributeUsage。为其他属性添加特殊处理需要修改编译器。
我认为唯一的万无一失的方法是扩展 Visual Studio(通过 VSIP)并订阅正确的事件(可能在 EnvDTE.BuildEvents 中)类,并检查您的代码是否使用了构造函数,如果您取消构建检测它。
这听起来有点像昨天的 TDWTF。:-)
我将不得不同意格雷格的观点:为它创造一个属性。
如果你真的很认真,也许可以找到一种方法来确定构造函数是否被 XMLSerializer 以外的任何东西访问,如果是则抛出异常。
我建议您使用 #error 指令。
另一个可能起作用的未知属性是条件属性(取决于您要达到的目标)
[Conditional("CONDITION")]
public static void MiMethod(int a, string msg)
如果定义了“MY_CONDITION”,它将从 IL 代码本身中删除方法调用。
创建一个 FxCop 规则,并将 FxCop 添加到您的集成构建中以检查这一点。
您将收到警告,而不是构建失败。属性在反射时间而不是构建时间“运行”。
或者(这是相当讨厌的)在您不想被调用的方法周围放置一个编译器指令。然后,如果您调用它,您的代码将会中断,但您可以设置一个传递正确编译器指令但不传递的构建。
抛出自定义异常并对其进行单元测试作为后期构建步骤
4年后回复:)
如果有过时的替代品,我也有同样的问题。
据我回忆(channel9 视频)不久前,微软表示它正在努力让开发人员在某个时候访问编译器 api 之类的东西,所以将来可以想象你可以编写一个编译器“插件”来允许用您自己的自定义属性装饰方法,并告诉编译器如果看起来装饰的代码可能在代码中的其他地方被调用,则取消。
当你想到它时,这实际上会很酷。它还提醒我,我还应该尝试阅读 MS 正在处理的那个编译器 api 的进展......
为什么不只是编造一些东西?未知属性肯定会破坏构建。
[MyMadeUpAttributeThatBreaksTheBuildForSure]
public class NotDoneYet {}