为过时的C#事件构建警告

Ori*_*meg 12 c# api events obsolete

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

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

项目1中的事件声明:

    public class APIClass
    {
        [Obsolete("Obsolete in v2.0")]
        public event EventHandler ObsoleteEvent;
    }
Run Code Online (Sandbox Code Playgroud)

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

    private void SubscribeToEvent(APIClass apiClass)
    {
        apiClass.ObsoleteEvent += delegate { };
    }
Run Code Online (Sandbox Code Playgroud)

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

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

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

LED*_*LED 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 { });
}
Run Code Online (Sandbox Code Playgroud)

我希望这个解决方法对您有用!祝你好运!

* 编辑 *

为了进一步说明为什么这是一个错误,请允许我向您展示此代码生成的 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
Run Code Online (Sandbox Code Playgroud)

这与我们编写的“AddListener”方法形成对比,我们手动添加了“Obsolete”属性。请注意,编译器已向该方法添加了“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.
Run Code Online (Sandbox Code Playgroud)

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