C#中与perl warn相对应的是什么?

5
在Perl中,我可以这样说:
use warnings;
warn "Non-fatal error condition, printed to stderr.";

这在C# ASP.NET中的等效物是什么?具体来说,我正在寻找的是其他团队成员可以知道他们是否仍在使用已弃用的例程。它应该在代码路径实际被触发时显示,而不是在编译时(否则,他们将收到有关代码坐在兼容性层上的警告,这些代码本来就不应该运行)。到目前为止,我最好的选择是使用Trace,但感觉像是一个糟糕的hack。

可能是重复问题:https://dev59.com/V0fSa4cB1Zd3GeqPBOxK - Michael La Voie
我并不认为这是重复的。每个原帖作者的参考框架都不同。 - David Morton
我认为在C#中,跟踪方法可能是您最好的选择。希望您针对事件日志进行警告消息的定位。真的认为[Obsolete]属性是您的最佳选择。 - No Refunds No Returns
我期望的目标是浏览器。开发人员可能永远不会查看充满警告信息的日志文件,但他们一定会查看页面源代码,并且无法忽略其中的内容。 - sorpigal
我在C#中想念警告。在Perl中,它们非常方便,因为你可以发出警告并捕获它,但代码仍然会继续执行。有点像不会停止代码的异常。 - Matthew Lock
7个回答

6

使用ObsoleteAttribute。将其放置在任何你想要标记为不建议使用的方法上面。这样,他们会在错误窗口中收到警告,但应用程序仍然可以编译。

public class Thing
{
     [Obsolete]
     public void OldMethod() { Console.WriteLine("I'm Old"); }
}

1
关于 ObsoleteAttribute 的一个注意事项有时会被忽视 - 你可以使用标志将一个成员标记为已弃用,从而导致编译时失败,但该成员仍然可以通过反射访问。如果你真的希望该成员不可调用,最好还要修改该成员的内容以抛出异常。 - plinth

4

编辑:我没有看到问题中说您希望在执行时进行。

写出数据执行时间的问题在于需要知道在哪里写入。你的应用程序通常使用什么日志记录形式?基本上使用相同形式的日志记录。

然而,我仍然更喜欢下面列出的编译时选项——您可以使用#pragma warn disable/restore关闭兼容层中的特定警告,但这将使问题更容易被发现,而不是希望有人读取日志文件...


旧答案

对于任何类型或成员,请使用[Obsolete]属性。您可以决定这是否应该成为警告或错误。例如:

using System;

class Test
{
    static void Main()
    {
        OldMethod();
        BadMethod();
    }    

    [Obsolete("Use something else instead")]
    static void OldMethod() {}

    [Obsolete("This would destroy your machine!", true)]
    static void BadMethod() {}
}

编译后的结果如下:

Test.cs(7,9): 警告 CS0618: 'Test.OldMethod()' 已过时: '请使用其他方法' Test.cs(8,9): 错误 CS0619: 'Test.BadMethod()' 已过时: '此方法将破坏您的计算机!'

理想情况下,该消息应解释继续使用该方法的影响以及建议使用的替代方法。

你说得对;跟踪和其他日志记录解决方案的问题在于“消息去了哪里?”在perl Web开发中,warn + CGI::Carp + warningsToBrowser会将消息作为注释发送到页面。ASP.NET跟踪类似,但会转储大量格式化数据,导致结果页面很杂乱。看起来Trace是最接近的答案。 - sorpigal

2
您可以使用 Trace.TraceWarning 来检测运行时过时方法的使用,但是您真的应该重新考虑您的设计并使用 ObsoleteAttribute 和编译时检测。
运行时检测此类错误应该是最后的手段。
如果您的兼容性层是自动生成的代码,则在生成 shim 时可以检查 ObsoleteAttribute 并标记这些 shim 为 [Obsolete]。
如果您的兼容性层使用反射,则可以检查 ObsoleteAttribute 并发出警告。
如果您的兼容性层是手动编写的,则可以编写一个工具,自动检查兼容性层中的 IL,并根据它们调用哪些方法将兼容性层方法标记为 [Obsolete]。
在每种情况下,最好将所有过时的方法都标记为 [Obsolete],以便新代码不会调用它们。
如果您的兼容性层包括调用过时方法的 shim,并且这些 shim 也被标记为 [Obsolete],则可以安全地使用以下方式进行编译:
#pragma warning disable 618

当编译兼容层时,这将隐藏过时的警告。由于您的兼容层方法也标记为 [Obsolete],因此您将在正确的位置收到警告。


Trace似乎是运行时警告的最佳解决方案。我喜欢你的[Obsolete] + #pragma解决方案,可以生成更好的编译时消息。尽管这不是我要求的,但我发现它非常有用。 - sorpigal

2

您需要了解的是,有一种#warning指令可以用于运行时警告生成; 然而,[Obsolete]属性更符合您的需求。


2
同样也要在编译时而非运行时。 - No Refunds No Returns

2

没有与warn__WARN__处理相对应的内容,但可以通过简单的Console.Error.WriteLine()调用打印到STDERR。

话虽如此,你真正想做的是标记某些内容已过时或不建议使用,其他人已经向你展示了如何做到这一点。请使用该方法,而不是将警告调用插入到函数中。


1

我认为Trace类是你最好的选择。根据你想要多么侵入性,你可以使用不同的跟踪级别甚至是Fail语句(这会弹出令人讨厌的断言对话框)。

private void SomeOldMethod()
{
  Trace.Fail("You shouldn't call this method"); // <-- this will bring up an assert dialog
  Trace.TraceWarning("You shouldn't call this method");
  Trace.TraceError("You shouldn't call this method");
}

0

在C#中标记方法为已弃用的方法是使用过时的属性,该属性被重载以输出消息(在智能感知中)和布尔值,以确定是否允许编译。但我并不完全确定这是否符合您的要求,因为我对Perl不熟悉。

[Obsolete("A message",false)]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接