草庐IT

c# - 为过时的 C# 事件生成警告

coder 2024-05-28 原文

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

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

项目一中的事件声明:

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

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

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

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

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

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

最佳答案

这似乎确实是一个公认的错误,但我可以想出一个解决方法,希望对您的情况有用。

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

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。类比事件关键字的行为类似于属性关键字,它会发出“add_ObsoleteEvent”和“remove_ObsoleteEvent”方法。您在编辑器中看不到它们,但它们是代码链接在一起的方式。

这是创建的添加方法。请注意,'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”属性。注意到编译器已将“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。我没有尝试过,所以我不能说它是否有效。但我想我会进行此编辑以说明出现问题的原因。希望对您有所帮助!

关于c# - 为过时的 C# 事件生成警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13720990/

有关c# - 为过时的 C# 事件生成警告的更多相关文章

  1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  2. ruby - 在院子里用@param 标签警告 - 2

    我试图使用yard记录一些Ruby代码,尽管我所做的正是所描述的here或here#@param[Integer]thenumberoftrials(>=0)#@param[Float]successprobabilityineachtrialdefinitialize(n,p)#initialize...end虽然我仍然得到这个奇怪的错误@paramtaghasunknownparametername:the@paramtaghasunknownparametername:success然后生成的html看起来很奇怪。我称yard为:$yarddoc-mmarkdown我做错了什么?

  3. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  4. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  5. ruby-on-rails - active_admin 目录中的常量警告重新声明 - 2

    我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA

  6. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  7. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  8. ruby-on-rails - Ruby on Rails - 为文本区域和图片生成列 - 2

    我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数

  9. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  10. ruby-on-rails - 我更新了 ruby​​ gems,现在到处都收到解析树错误和弃用警告! - 2

    简而言之错误:NOTE:Gem::SourceIndex#add_specisdeprecated,useSpecification.add_spec.Itwillberemovedonorafter2011-11-01.Gem::SourceIndex#add_speccalledfrom/opt/local/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:91./opt/local/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/rails/gem_dependency.rb:275:in`==':und

随机推荐