在C#(或任何语言)中,您最喜欢的删除重复的方式是什么?

时间:2008-09-12 22:39:34

标签: c# coding-style refactoring

我刚编了一个700线的课程。可怕。我羞愧地低下头。这与英国夏天的DRY相反。

它充满了剪切和粘贴,并且有轻微的调整。这使得它成为重构的主要候选者。在我开始这个之前,我想我会问你什么时候有很多重复,你要找的第一个重构机会是什么?

为了记录,我的可能正在使用:

  1. 通用类和方法
  2. 方法重载/链接。
  3. 你的是什么?

7 个答案:

答案 0 :(得分:4)

我喜欢在需要时开始重构,而不是第一次获得机会。您可能会说这在某种程度上是一种敏捷的重构方法。我什么时候需要?通常当我觉得我的代码的丑陋部分开始传播时。只要它们被包含在内,我认为丑陋是可以的,但是当它们开始有传播的冲动时,那就是你需要照顾生意的时候。

您用于重构的技术应该从最简单的开始。我强烈推荐Martin Fowler的书。将公共代码组合到函数中,删除不需要的变量以及其他简单的技术可以获得很多里程。对于列表操作,我更喜欢使用函数式编程习语。也就是说,我使用内部迭代器,map,filter和reduce(在python中说,ruby,lisp和haskell中有相应的东西),只要我能,这会使代码更短,更自包含。

答案 1 :(得分:2)

#地区

我用它只用了1000行一行!

严肃地说,避免重复的最好方法是列表中包含的内容,以及充分利用多态性,检查你的类并发现在基类中最好的做法,以及它的不同组成部分如何被打破了一个子类。

答案 2 :(得分:2)

有时候,当你使用复制和粘贴代码“完成功能”时,你已经达到了这样的程度,即它已经被残留并且受到严重破坏,任何重构的尝试实际上都需要花费很多时间,比重构它的时间要长得多它显而易见的地方。

根据我的个人经验,我最喜欢的“删除重复的方法”是Resharper的“提取方法”功能(虽然这也可以在vanilla Visual Studio中使用)。

很多时候,我会看到重复的代码(我正在维护的一些遗留应用程序)不是完整的方法,而是在完全独立的方法中的块中。这给了将这些块变成方法的绝佳机会。

Monster类也倾向于揭示它们包含多个功能。这反过来成为将每个不同功能分成自己(希望更小)的类的机会。

我必须重申,做所有这些并不是一种愉快的体验(对我而言),所以我真的宁愿做正确的事情,因为它是一个小小的泥球,而不是让泥球滚滚而且然后尝试解决这个问题。

答案 3 :(得分:1)

首先,我建议比完成第一个版本的课程更快地进行重构。任何时候你看到重复,尽快消除它。这最初可能需要更长的时间,但我认为结果会更加清晰,并且可以帮助您重新考虑代码,以确保您做得对。

至于我最喜欢的删除重复的方式....闭包,尤其是我最喜欢的语言(Ruby)。它们往往是一种非常简洁的方式来获取2个代码并合并相似性。当然(像任何“最佳做法”或提示),这不能盲目地完成......我发现当我可以使用它们时,它们真的很有趣。

答案 4 :(得分:1)

我做的一件事就是尝试制作一些小而简单的方法,我可以在编辑器(visual studio)的单个页面上看到。

我从经验中学到,使代码变得简单使编译器更容易优化它。方法越大,编译器就越难工作!

我最近也看到了大型方法导致内存泄漏的问题。基本上我有一个非常像下面的循环:

while (true)
{
  var smallObject = WaitForSomethingToTurnUp();
  var largeObject = DoSomethingWithSmallObject();
}

我发现我的应用程序在内存中保留了大量数据,因为即使'largeObject'不在范围内,只有smallObject返回了一些内容,垃圾收集器仍然可以看到它。

我通过将'DoSomethingWithSmallObject()'和其他相关代码移动到另一个方法轻松解决了这个问题。

此外,如果您制作小方法,您在类中的重用将变得更高。我一般都试图确保我的方法都不像其他方法!

希望这有帮助。

尼克

答案 5 :(得分:1)

“在这里和那里进行小调整的剪切和粘贴”是我通常使用完全非外来方法解决的代码重复类型 - 采用类似的代码块,将其提取为单独的方法。在该代码块的每个实例中都有所不同,将其更改为参数。

还有一些简单的技术可以删除重复的if / else if和switch块,Scott Hanselman提供: http://www.hanselman.com/blog/CategoryView.aspx?category=Source+Code&page=2

答案 6 :(得分:1)

我可能会这样:

为数据结构创建自定义(私有)类型,并将所有相关逻辑放在那里。字典< string,List< int>>等

制作保证行为的内部功能或属性。如果您不断检查公共可访问属性的条件,则创建一个私有的getter方法,其中包含所有检查。

除了太多的分裂方法之外。如果你不能把简洁的东西放到或给它一个好名字,那么就开始分开函数,直到代码为止(即使这些“子”函数没有在其他任何地方使用)。

如果所有其他方法都失败了,请打一个[SuppressMessage(“Microsoft.Maintainability”,“CA1502:AvoidExcessiveComplexity”)]并评论原因。