12

有谁知道在使用 Obsolete 事件时让 Visual Studio C# 编译器发出构建警告的技巧或解决方法?

如果我创建一个带有公共事件的简单程序集并将 Obsolete 属性应用于该事件,当我引用该程序集并在另一个项目中订阅该事件时,编译器在我构建时不会发出警告(即使是最高警告级别或警告设置为错误)。

项目 1 中的事件声明:

    public class APIClass
    {
        [Obsolete("Obsolete in v2.0")]
        public event EventHandler ObsoleteEvent;
    }

在 Project 2 中使用 Obsolete 事件不会导致生成警告:

    private void SubscribeToEvent(APIClass apiClass)
    {
        apiClass.ObsoleteEvent += delegate { };
    }

当我打开源文件时,Visual Studio 将事件识别为已过时并将警告(或错误)添加到错误列表中: 后台源处理识别警告

但是,一旦我构建,警告就会消失并且不会出现在构建输出中: 编译后警告消失

缺少的编译器警告似乎已作为错误提交,但在修复之前,是否有任何方法可以在有人使用该事件时强制发出警告?否则无法提醒外部消费者他们需要更改调用代码。

4

1 回答 1

4

这似乎是一个公认的错误,但我可以想到一个解决方法,我希望它适用于您的情况。

event 关键字只是符合特定签名的多播委托的语法快捷方式,并以类似的方式巧妙地将自身暴露给属性。您可以尝试的一种解决方案是将事件设为私有,并公开一种添加侦听器的方法,然后将其标记为已过时:

public class APIClass
{
    [Obsolete("Obsolete in v2.0")]
    private event EventHandler ObsoleteEvent;

    [Obsolete("Obsolete in v2.0")]
    public void AddListener(EventHandler eh)
    {
        ObsoleteEvent += eh;
    }

}

private static void SubscribeToEvent(APIClass apiClass)
{
    //apiClass.ObsoleteEvent += delegate { };
    apiClass.AddListener(delegate { });
}

我希望这项工作对您有用!祝你好运!

* 编辑 *

为了进一步说明为什么这是一个错误,请允许我向您展示此代码生成的 MSIL。类似于 event 关键字的行为类似于 property 关键字,它发出一个“add_ObsoleteEvent”和一个“remove_ObsoleteEvent”方法。您在编辑器中看不到它们,但它们是代码链接在一起的方式。

这是创建的 add 方法。请注意,'Obsolete' 属性未添加到编译器生成的方法中?

.method private hidebysig specialname instance void 
        add_ObsoleteEvent(class [mscorlib]System.EventHandler 'value') cil managed
{
  // Code size       48 (0x30)
  .maxstack  3

/// rest omitted

这与我们编写的“AddListener”方法形成鲜明对比,我们手动添加了“Obsolete”属性。请注意编译器已将“过时”属性添加到方法中?

.method public hidebysig instance void  AddListener(class [mscorlib]System.EventHandler eh) cil     managed
{
  .custom instance void [mscorlib]System.ObsoleteAttribute::.ctor(string) = ( 01 00 10 4F 62 73     6F 6C 65 74 65 20 69 6E 20 76   // ...Obsolete in v
                                                                              32 2E 30 00 00 )                                      // 2.0..
  // Code size       10 (0xa)
  .maxstack  8

/// rest omitted.

要使其在编译时远离编辑器发出警告,可以手动将其添加到 MSIL。我还没有尝试过,所以我不能说它是否有效。但我想我会进行此编辑以说明问题发生的原因。我希望它有帮助!

于 2012-12-05T17:23:47.120 回答