【问题标题】:How to write a code with expiration date?如何编写带有到期日期的代码?
【发布时间】:2011-03-07 16:15:26
【问题描述】:

我刚刚有了一个我希望能够使用的东西的想法:

假设我必须修复一个错误,并且我决定编写一个丑陋的代码行来修复当前的问题 - 但这只是因为我向自己保证我很快就会找到时间进行适当的重构。

我希望能够以某种方式将该代码行标记为“已过期”并添加一个日期 - 这样,如果在该日期之后的某个时间编译代码,则会出现编译错误/警告并显示正确的消息。

有什么建议吗?必须可以执行 - 也许使用一些复杂的#IF 或 Visual Studio 中的一些选项? 我正在使用 VS 2005 - 主要用于 C#。

谢谢!

[编辑]:哇——没想到这个问题会引起如此多的兴趣:) 谢谢大家的回答,感谢你们把这变成了一场有趣的辩论。 我知道很难证明使用这样的东西是合理的——我可能不会使用它——但有时,当你必须在昨天发布一个版本时,你发现自己在一个不完整的修复上妥协——你想强迫自己修复它在不久的将来。

我选择 MartinStettner 的建议作为答案,因为它满足了我的需求 - 运行时没有错误 - 仅在编译期间,无需仅为此目标定义新类型 - 而且它不限于整个方法的范围。干杯!

【问题讨论】:

  • 我认为这是一个糟糕的主意。这与借钱买买不起的房子几乎是一样的概念。如果您现在没有时间正确编写代码,那么您,或者任何可怜的草皮在以后维护您的黑客,在未来的某个任意日期有什么机会?我讨厌它在太多层面上无法解释。
  • 手榴弹 - 虽然我原则上完全同意(我一直在那里收拾残局),但我确实认为这是一个相当古怪的想法。
  • @jim 绝对是,我什至用条件属性自己尝试了一次失败的尝试。我喜欢你的例子顺便说一句。从有趣的编码问题的角度来看,这是一个有趣的问题。从 IDE 中的工具支持的角度来看,它鼓励新开发人员及早且经常陷入代码债务,这很糟糕!
  • 手榴弹 - 是的,100% 的课程马...到期:)
  • @grenade - 喜欢! :) 我完全同意 - 但有时 - 只是有时......你真的需要它。

标签: c# visual-studio coding-style


【解决方案1】:

System.ObsoleteAttribute属性标记代码,你会得到一个编译器警告,它会提醒你修复代码

[Obsolete("You've an ugly hack here")]
public void MyUglyHack()
{
...
}

或者。 . .

编写你自己的属性,在构造函数中传递一个过期日期,如果DateTime.Now >= expirationDate在构造函数中抛出异常。

编译将失败,直到您修复代码(或者更有可能增加到期日期,或者更有可能您只需删除属性。

【讨论】:

  • 我认为Obsolete 只会在某处实际调用该方法时发出警告。如果它被称为例如它没有警告。通过接口(即接口方法未标记为过时,但某些实现方法已过时),或者 - 更糟糕的是 - 它通过反射调用。此外,您只能将整个方法标记为过时,而我认为 OP 想要标记单行或代码段。
  • +1 表示“...或者更有可能您只是删除了属性。”
【解决方案2】:

ooohhh - 这太糟糕了。试试这个咯:

[AttributeUsage(AttributeTargets.All)]
public class BugExpiryAttribute : System.Attribute
{
    // don't tell 'anyone' about this hack attribute!!
    public BugExpiryAttribute(string bugAuthor, string expiryDate)
    {
        DateTime convertedDate = DateTime.Parse(expiryDate);
        Debug.Assert(DateTime.Now <= convertedDate, 
            string.Format("{0} promised to remove this by {1}", 
                bugAuthor, convertedDate.ToString("dd-MMM-yyyy")));
    }
}

然后,装饰您的方法/类等:

[BugExpiryAttribute("Jack Skit", "2011-01-01")]
public static void Main(string[] args)
{
...
}

...讨厌:-)

[免责声明] - 以学术兴趣的名义创建,而不是生产代码精巧!!

[编辑] - 澄清一下,编译和生产中的代码将在“bugExpriryDate”之后/之后继续运行。只有在编译器中运行代码后(在日期/日期之后),才会引发警告消息(debug.assert)。只是认为值得做出这样的区分——MartinStettner 欢呼。

[警告] - 如果在类/方法等中使用,则需要通过反射读取。但是(这很有趣)如果在sub Main() 上使用,它将直接在编译器中工作。多奇怪!! (感谢点头汉斯...)

【讨论】:

  • 嘘——有人投了反对票,但没有说明原因,即使我清楚地说明了情况..(大眼泪图标)。你的幽默感/冒险小伙子(或小妞)在哪里!! ;'')
  • 不错!如果您将属性参数设置为“2012-12-21”,那么只要我们都在这里,就可以使用 MyUglyHack()。 ;)
  • 'eggzakly...' :-)。在那张纸条上,现在是时候了。祝你晚上愉快。 ;)
  • +1 为证明这实际上是可能的而投赞成票。我很想看到纯 C 的相同演示......它必须使用预处理器魔法来完成。或者带有模板元编程的 C++....
  • 这段代码什么都不做。如果没有读取它们的代码,属性将毫无用处。编译器肯定不会。
【解决方案3】:

我认为这就是 Visual Studio 有一个任务列表的原因。添加评论:

\\ TODO: Fix this spaghetti by 01APR11

它会像这样显示

.

关键字可从选项中配置

【讨论】:

  • 我在大多数项目中都使用 Doxygen。这是一个很好的做法,可以注意到如果观察到瓶颈可以采取不同的方式做的事情,但显然不值得在即时截止日期前进行。
【解决方案4】:

您可以在表单中写注释行

// Expires on 2011/07/01

并添加一个预构建步骤,该步骤在解决方案范围内将这些行替换为类似

#error Code expired on 2011/07/01

对于包含当前日期之前的日期的所有行。对于这个预构建步骤,您需要编写一个简短的程序(可能使用正则表达式和一些日期比较逻辑)

此步骤也可以由 VS 宏执行,它允许更轻松地访问解决方案的所有文件,但缺点是必须在编译项目的所有 VS 安装上安装和运行它。

【讨论】:

  • +1 我最喜欢这个解决方案。您也可以轻松地将它添加到您的 CD 脚本中。
  • 只是想补充一点,创建一些 VS 插件可能会更好,它将作为预构建操作执行此操作。这将省去向每个项目添加操作的需要。
  • Netbeans(Java)有什么解决方案吗?
【解决方案5】:

如果您对代码进行了单元测试,则还有一个选择,您可以定时轰炸验证您的修复的测试。这样您就不会在生产代码中引入奇怪的检查。

此外,我认为最好的选择是如果您必须进行 hack(您可能已经花了足够的时间查看它以正确修复......但仍然想要在那里进行 hack)而不是打开错误/创建任务/工作项(无论您使用什么来跟踪未来的工作)并决定以后是否要修复它。

【讨论】:

  • 好点。在测试中实施“唠叨”检查将是这两个弊端中较小的一个。有趣...
  • 是否有任何库为 golang 提供此功能?或博客提供一些关于这个概念的见解?
【解决方案6】:

好吧,它并不能完全满足您的要求,但您可以使用 Debug.Assert() 方法调用,它会提醒您(仅在 Debug 中)代码已过期。一个好处是它不会无意中影响您的生产代码(编译或执行),但在 Debug 中会很烦人,以至于您想要更正它。

// Alert the developer after 01/07/2011
Debug.Assert(Date.Now < new DateTime(2011, 7, 1))

【讨论】:

  • 现在,如果您可以将其重构为与 System.ObsoleteAttribute 属性类似的实现,那可能会很有趣。
【解决方案7】:

如果不控制编译器(可能在 5.0 的时间范围内将编译器作为服务?),您的代码不会过期。您可以将代码标记为已弃用,或使用 Obsolete 属性或类似属性来触发警告,但人们可以忽略警告(我遇到的许多开发人员还没有了解警告是错误的规则)。

我认为保护人们免受自身伤害是一项艰巨的工作。当你在未来保护他们免受自己的伤害时,这就更难了。将代码标记为 kludge 并保留它。

【讨论】:

    【解决方案8】:

    与其嵌入定时炸弹,不如考虑应用BUGBUG: comment

    与其强迫您或其他人修复可能有点难看但按预期工作的代码,您可以在解决方案范围内进行搜索,并在您决定该停下来时找到丑陋的部分重构真正丑陋的东西。

    【讨论】:

      【解决方案9】:

      改为在错误中跟踪它。然后它可以与其他重构工作一起被适当地安排和优先排序。

      TODO 代码中的 cmets 可能容易丢失和遗忘。在特定日期之后引发编译器错误可能会导致该日期被提前,或者评论/属性被删除。

      【讨论】:

        【解决方案10】:

        我希望我能帮上忙。在工具箱上取 2 个 datetimepicker。只需转换 1 个日期时间选择器。

        private void expired()
        {
        DateTime expired = DateTime.Parse(Convert.ToDateTime(datetimepicker1.Text).ToString());
        DateTime compare = DateTime.Parse(Convert.ToDateTime(datetimepicker2.Text).ToString());
        
        if(expired < compare)
        {
        MessageBox.Show("This product is expired!");
        }
        else
        }
        MessageBox.Show("This product is not expired");
        {
        }
        

        【讨论】:

          【解决方案11】:

          TIMEDATE 都发出字符串,据我所知,在预处理阶段无法解析它们。

          您可以在代码中轻松执行一些方法,以确保代码至少在运行时向您发出警告。包含断言是一种方法,添加代码注释也可以,但我处理它的方式是通过包含 doxygen 注释和注释,说明该函数包含需要解决的 hack、bug 或性能问题。这最终会被许多程序员过滤,并且很容易在网站上查看,供我自己或其他人修复。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-12-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多