C#允许使用#region / #endregion关键字来使代码区域在编辑器中可折叠。每当我这样做时,我都会隐藏可能会重构为其他类或方法的大量代码。例如,我见过一些方法,其中包含500行代码(带有3个或4个区域),只是为了使其易于管理。

那么明智地使用区域是否会带来麻烦?对我来说似乎是这样。

评论

仅供参考:CodeMap几乎消除了对区域的需求。 visualstudiogallery.msdn.microsoft.com/…-单击,然后您进入方法/属性/其他。我每天都在使用它,这真是令人惊讶,您从生产力和认知方面也获得了多少收益。您将获得该班级更为清晰的“鸟瞰图”。

任何人都可以将此作为Wiki吗?这个问题没有正确或错误的答案(在合理范围内),这几乎是完全主观的。

对于价值而言,杰夫·阿特伍德(Jeff Atwood)讨厌他们。他辩称他们隐藏了错误的代码。

代码气味是不淋浴也不使用除臭剂的开发人员!

Febreeze在硬皮沙发上挤了几下,用臭代码精心制作了Regions。它使您可以忍受,直到找到(时间)钱来代替它。

#1 楼

代码气味是一种症状,表明设计中存在一个问题,这可能会增加错误的数量:对于区域而言,情况并非如此,但是区域可能会导致产生代码气味,就像长方法一样。

由于:


反模式(或反模式)是在社交或业务运营或软件工程中使用的模式,可能会普遍使用,但在模式中无效和/或适得其反实践


区域是反模式。他们需要做更多的工作,这些工作不会提高代码的质量或可读性,也不会减少错误的数量,并且可能只会使代码更难以重构。

在方法内部使用区域;重构

方法必须简短。如果一个方法中只有十行,则在处理其他五行时可能不会使用区域来隐藏其中的五行。

此外,每种方法都只能做一件事。另一方面,区域旨在分离不同的事物。如果您的方法先执行A,然后执行B,则创建两个区域是合乎逻辑的,但这是错误的方法。相反,您应该将方法重构为两个单独的方法。在这种情况下,使用区域也会使重构更加困难。想象一下,您有:

private void DoSomething()
{
    var data = LoadData();
    #region Work with database
    var verification = VerifySomething();
    if (!verification)
    {
        throw new DataCorruptedException();
    }

    Do(data);
    DoSomethingElse(data);
    #endregion

    #region Audit
    var auditEngine = InitializeAuditEngine();
    auditEngine.Submit(data);
    #endregion
}


让第一个区域集中精力于第二个区域不仅冒险,我们还可以轻松地忘记停止流动的异常(可能是因为带有return的guard子句,这更加难以发现),但是如果应该以这种方式重构代码,也会有问题:

private void DoSomething()
{
    var data = LoadData();
    #region Work with database
    var verification = VerifySomething();
    var info = DoSomethingElse(data);

    if (verification)
    {
        Do(data);
    }

    #endregion

    #region Audit
    var auditEngine = InitializeAuditEngine(info);
    auditEngine.Submit(
        verification ? new AcceptedDataAudit(data) : new CorruptedDataAudit(data));
    #endregion
}


现在,区域没有意义,如果不查看第一个区域中的代码,就无法阅读和理解第二个区域中的代码。

我有时看到的另一种情况是:

public void DoSomething(string a, int b)
{
    #region Validation of arguments
    if (a == null)
    {
        throw new ArgumentNullException("a");
    }

    if (b <= 0)
    {
        throw new ArgumentOutOfScopeException("b", ...);
    }
    #endregion

    #region Do real work
    ...
    #endregion
}


当参数验证开始跨越数十个LOC时,很容易使用区域,但是有一种更好的方法来解决此问题:.NET Framework源代码使用的一种方法:

public void DoSomething(string a, int b)
{
    if (a == null)
    {
        throw new ArgumentNullException("a");
    }

    if (b <= 0)
    {
        throw new ArgumentOutOfScopeException("b", ...);
    }

    InternalDoSomething(a, b);
}

private void InternalDoSomething(string a, int b)
{
    ...
}


不要使用方法外部的区域来分组


有人用它们将字段,属性等分组在一起。这种方法是错误的:如果您的代码兼容StyleCop,那么字段,属性,私有方法,构造函数等已被分组在一起,很容易找到。如果不是,那么是时候开始考虑应用确保整个代码库统一的规则了。
其他人使用区域来隐藏很多相似的实体。例如,当您有一个包含一百个字段的类(如果计算注释和空格,则至少要编写500行代码),您可能会想将这些字段放在一个区域内,将其折叠并忘记它们。再一次,您做错了:在一个类中有这么多字段,您应该更好地考虑使用继承或将对象分割为几个对象。
最后,有些人很想使用区域将相关的东西组合在一起:具有其委托的事件,或与IO相关的方法,以及与IO相关的其他方法,等等。在第一种情况下,事件变得一团糟,难以维护,阅读和理解。在第二种情况下,更好的设计可能是创建多个类。

区域是否有很好的用途?

否。有一个遗留用途:生成的代码。尽管如此,代码生成工具只需要使用部分类即可。如果C#具有区域支持,则主要是因为这种旧式使用,并且由于现在有太多人在其代码中使用区域,因此在不破坏现有代码库的情况下就不可能删除它们。

考虑一下goto。语言或IDE支持功能这一事实并不意味着应每天使用它。 StyleCop SA1124规则很明确:您不应使用区域。永远不会。

示例

我目前正在对同事的代码进行代码审查。该代码库包含许多区域,并且实际上是如何不使用区域以及区域为何导致不良代码的完美示例。以下是一些示例:

4000 LOC怪物:

我最近在Programmers.SE上的某个地方读到,当文件包含太多using时(执行“删除”后, “未使用的用户”命令),则表明此文件中的类做得太多了,这是一个好兆头。文件本身的大小也一样。

在查看代码时,我遇到了一个4000 LOC文件。看起来,这段代码的作者只是简单地将同一行的15行方法复制粘贴了数百次,只是略微更改了变量名和被调用方法。一个简单的正则表达式允许通过添加一些泛型将文件从4000 LOC减少到500 LOC。我敢肯定,通过更巧妙的重构,此类可以减少到几十行。

通过使用区域,作者鼓励自己忽略以下事实:代码无法维护且编写不佳,并且大量复制代码而不是重构代码。

区域“ Do A”,区域“ Do B”:

另一个很好的例子是怪物初始化方法仅执行任务1,然后执行任务2,然后执行任务3,依此类推。有五个或六个完全独立的任务,每个任务在容器类中进行初始化。所有这些任务都被分组为一个方法,并分组为区域。

这有一个优点:


通过查看区域名称。话虽如此,重构后的相同方法将与原始方法一样清晰。

另一方面,问题是多方面的:


地区之间是否存在依赖关系并不明显。希望不会重用变量。否则,维护工作可能更是一场噩梦。
这种方法几乎无法测试。您怎么容易知道一次执行20件事的方法是否正确?

字段区域,属性区域,构造函数区域:许多区域将所有字段组合在一起,所有属性都组合在一起,等等。这存在一个明显的问题:源代码增长。

打开文件并查看大量字段时,您会发现更多倾向于首先重构类,然后使用代码。使用区域时,您会习惯于折叠东西而忘却它。

另一个问题是,如果在任何地方都进行操作,您会发现自己创建了一个整体的区域,这并没有使任何区域感。在我所检查的代码中实际上就是这种情况,其中有很多#region Constructor包含一个构造函数。最后,字段,属性,构造函数等应该已经按顺序排列。如果它们是并且它们符合约定(以大写字母开头的常量等),则已经很清楚元素类型在何处停止而其他在何处开始,因此您无需为此显式创建区域。

评论


我认为#region至少有一些可辩护的用途-例如折叠保护子句(检查输入参数),如果不折叠,则会破坏方法的要旨或“实质”。另一个例子是API边界上的异常处理。您通常不想通过调用其他方法包装异常来影响堆栈跟踪,因此您需要包装几行代码并重新抛出。这通常也是不相关的代码,可以安全地折叠起来。

–丹尼尔B
2012年6月6日上午8:24

现实检查。我已经看到很多方法间的#region很有帮助。当您有了带有嵌套控制逻辑的数百行方法时,其中有数十行至数百行,其中有一些-谢天谢地,白痴至少将其放置在区域中。

– radarbob
13年3月27日在22:14



@radarbob:简而言之,区域有助于编写糟糕的代码,而这些代码本来不应该存在。

– Arseni Mourzenko
13年3月28日在8:35

-1(如果我有声誉)。即使您的类型成员井井有条且相互独立,也可能会有很多人。区域使您不必滚动到10或12个属性以及相关的getter和setter即可滚动到要使用的方法。唯一的选择是分别折叠所有属性,这不是我喜欢的。提供的大规模显示/隐藏功能区域非常有用。我同意方法内区域。

–阿萨德·塞德丁(Asad Saeeduddin)
13年8月1日在20:26



我完全不同意这个答案:代码臭味和区域彼此无关。如果您的代码发臭,无论有无区域,它都会发臭。我使用区域的方式是将我的班级分成区域。通常,我仍然坚持相同的模式:公共属性,公共方法,私有字段,私有方法。那是我将拥有区域的唯一用途。除此之外,您可能在代码中破坏了SRP主体。

– Alexus
2015年6月23日在20:19



#2 楼

对我来说,令人难以置信的是,有多少人如此讨厌区域!

我完全同意他们的许多反对意见:将代码隐藏到#region中以将其隐藏起来是一件坏事。当应该将其重构为单独的类时,将一个类划分为#regions显然是错误的。使用#region嵌入冗余语义信息是多余的。

但是,这些都没有意味着在代码中使用区域本质上是错误的!我只能假设大多数人的反对意见来自在其他人倾向于错误地使用IDE功能的团队中工作。我拥有独自工作的能力,我很欣赏地区帮助组织工作流程的方式。也许这是我的强迫症,但我不喜欢一次在屏幕上看到一堆代码,无论它写得多么整洁。将事物分成逻辑区域,使我可以折叠我不关心的代码,以处理我关心的代码。我并不是在忽略写得不好的代码,对其进行重构比任何意义都没有意义,而且附加的“元”组织是描述性的,而不是毫无意义的。

既然我花了更多时间在C ++中工作,更直接地使用Windows API进行编程,我发现自己希望对区域的支持与对C#的支持一样好。您可能会争辩说,使用备用GUI库会使我的代码更简单或更清晰,从而消除了将无关的代码噪声从屏幕上移开的需要,但是我还有其他不想这样做的原因。我对键盘和IDE十分精通,可以使扩展/折叠细分为区域的代码花费的时间不到一秒钟。我节省了精力,试图将我的注意力集中到我目前正在处理的代码上,这是值得的。它们全都属于一个类/文件,但并非同时都属于我的屏幕。

要点是,使用#regions分离并按逻辑划分代码不是什么坏事不惜一切代价避免的事情。正如Ed所指出的,这不是“代码异味”。如果您的代码有味道,则可以确保它不是来自区域,而是来自您尝试将其埋在这些区域中的任何代码。如果某个功能可以帮助您更井井有条或编写更好的代码,那么我说可以使用它。如果它成为障碍,或者您发现自己使用不正确,请停止使用它。如果最糟糕的情况变得更糟,并且您被迫与使用它的人一起工作,请记住键盘快捷键以关闭代码概述:Ctrl + M,Ctrl + P。别抱怨了有时候,我觉得这是另一种方式,那些希望被视为“真实”,“核心”程序员的人喜欢尝试证明自己。避开区域比避开语法着色更好。但这并不能使您成为一个更具男子气概的开发人员。

所有这些,方法中的区域纯粹是胡说八道。每当您发现自己想要这样做时,都应该将其重构为一个单独的方法。没有借口。

评论


说得好。使用区域进行组织仅比切换IDE的“视图空白”选项有害。这是个人喜好。

–乔什
2011年3月1日下午6:50

我使用带有10或20个属性的ViewModels在WPF上工作,这些属性仅将属性包装在我的模型上,我喜欢区域-我可以将那些属性藏在一个区域中(它们永远都不需要被触摸),并一直关注相关代码。

–柯克·布罗德赫斯特(Kirk Broadhurst)
2011年3月1日在6:57

完全同意。在.NET 2.0中,属性的长度约为8-10行。当一个类中有20个以上的属性时,它们将占用大量空间。区域非常适合折叠它们。

–克里斯托夫·克莱斯(Kristof Claes)
2011年3月1日7:50

@Kristof:.NET 4.0中的属性也可以进行简单的输入验证。自动属性对于我来说并不是那么神奇。

–科迪·格雷
2011-3-1在7:53

我愿意向左打赌,那些讨厌地区的人要么从未开发过WPF应用程序,要么从未真正使用过WPF的定义功能,例如数据绑定和命令绑定。仅仅设置代码以使这些工作占用大量空间,并且您通常不必再次查看它们。

–l46kok
2012年11月28日在7:53

#3 楼

首先,我再也受不了“代码气味”这个词了。它使用得太频繁了,并且大部分时间都被无法识别好的代码的人扔掉。无论如何...

我个人不喜欢使用很多地区。这使获取代码变得更加困难,并且代码是我感兴趣的代码。当我有很多不需要经常接触的代码时,我喜欢使用区域。除此之外,它们似乎妨碍了我,“私有方法”,“公共方法”等区域使我发疯。它们类似于对i++ //increment i的注释。

我还要补充一点,使用区域并不能真正成为“反模式”,因为该术语通常用于描述程序逻辑/设计模式,而不是文本编辑器的布局。这是主观的;使用对您有用的东西。由于您对区域的过度使用,您永远都不会以无法维护的程序告终,这就是反模式的全部意义所在。 :)

评论


通常,我会为您的代码气味注释而投票,但是在这种情况下,它是准确的。非代码不能成为代码的味道。 +2!

–́Мסž
2011年3月1日,0:06

哈哈,嗯,我并不是说“代码气味”一词不能正确使用。可以,但是我看到这些天来了那么多,以至于我的直接反应就是烦恼,尤其是当来自真正只是在重复他们听到的声音而又不理解它或不认真思考的人。诸如“函数中超过5个局部变量是代码味道”之类的语句仅说明该人实际经验很少。

– Ed S.
2011-3-1在0:11



不确定我是否理解您对代码气味的评论。代码气味并不表示存在问题,只是可能存在问题。

– Craig
2011年3月1日下午0:51

+1代表术语代码气味。当我看到一则声称私有方法是代码气味的帖子时,我受够了。但是总的来说,我不同意你对地区的厌恶。我很容易分心。实际上,如果VS具有VB4模式(您一次只能显示一个方法),我将非常喜欢。

–乔什
2011年3月1日下午6:06

只是想插话并说滥用一个完美的隐喻不应贬低这个隐喻。 “代码气味”是一个很好的隐喻,可以立即理解,记住和使用。在很多地方,应用“代码气味”隐喻仍然是传达观点的最佳方法。

–埃里克·金(Eric King)
2012年6月5日20:22

#4 楼

是的,区域是代码的味道!

我很高兴看到完全从编译器中删除的区域。每个开发人员都会想出自己的毫无意义的修饰方案,这对其他程序员永远都不会有价值。我与希望装饰和美化他们的婴儿的程序员有关,而与任何真正的价值都没有关系。

您能想到一个例子吗,尽管“老兄,我希望我的同事使用了一些东西。即使在我可以配置我的IDE来自动扩展所有区域的情况下,它们仍然令人大开眼界,并且有损于阅读真实的代码。

我' d如果我所有的公共方法都聚集在一起,还是真的不太在意。恭喜,您知道变量声明和初始化之间的区别,无需在代码中显示它!

无值修饰!

另外,如果您的文件需要使用“信息体系结构”使用区域可能要解决的核心问题:您的课程太大了!将其分解成较小的部分会更加有益,并且如果正确完成,则会增加真正的语义/可读性。

评论


#regions是编译器的一部分吗?我认为它们只是对IDE的指令,可以忽略。

– Steve Rukuts
2011年7月13日在11:30

编译C#代码时,编译器将需要忽略它们。如果不忽略它们,它将对它们产生影响。我是那样说的。

–乔普
2012年12月13日下午1:55

“您能想到一个例子,您虽然说“老兄,我希望我的同事在这里使用过一些区域!”?”是的,非常非常。当我有一个包含私有方法和公共方法的类时,我会在区域中将它们分解,因为重构公共方法时,您不必触摸私有代码,反之亦然。

– Anshul
15年8月27日在17:24



您显然从未见过外包代码。因此,很多时候在外包代码中看到区域会很棒。即使代码很烂,但如果从某种逻辑上讲将它们组合在一起,那么至少至少会更容易理解。虽然,如果他们的代码不是合乎逻辑的机会,那么区域也不会是这样,那么可能会使情况变得更糟。如果正确使用,区域会很棒。

– NickMCcomb
17年8月24日在2:30

#5 楼

我个人使用区域作为将各种类型的方法或部分代码组合在一起的一种方式。

因此打开代码文件可能如下所示:


公共属性
构造函数
保存方法
编辑方法
专用助手方法

我没有将区域放在方法内。恕我直言,这是代码气味的迹象。我曾经遇到过一种方法,该方法长1200行以上,其中有5个不同的区域。真是恐怖的景象!

如果您使用它来组织代码的方式可以使其他开发人员更快地找到内容,那么我认为这不是麻烦的迹象。如果您使用它来隐藏方法内部的代码行,那么我想是时候重新考虑该方法了。

评论


啊。我知道这是一个主观的话题,但是,我真的受不了这个计划。以我的经验,添加的“组织”根本无济于事,只是让浏览代码变得头疼。我还更喜欢不仅按访问修饰符而且按逻辑责任进行分组的方法。对于公共接口,我通常将每个方法/属性分组在一起,但是通常受保护的方法可能会调用私有帮助器函数,在这种情况下,我更喜欢帮助器函数(只能在其中使用)在该函数的上方或下方。调用它的方法。

– Ed S.
2011-2-28在23:32



@Ed S.-这就是为什么我说“可能看起来像”。这是非常主观的。我并不是说每个文件都应该像这样。如果他们这样做,我会感到惊讶。只是有关复杂主题的示例。 :)

–蒂安娜
2011-2-28在23:48

哦,我知道,就像我说的那样;这是主观的。对您/您的团队有用的任何东西。我只是为这个方案准备了它,因为它对我不起作用,但是我必须维护一个做到这一点的项目。这让我发疯。

– Ed S.
2011-02-28 23:49



@EdS。因此,请进入vs中的选项并关闭区域。问题解决了。

–安迪
2015年8月1日在20:33

为什么您的对象具有保存方法? :(

–TheCatWhisperer
17年3月17日在18:55

#6 楼

使用#region块使非常大的类可读性通常是违反单一责任原则的标志。如果他们习惯于对行为进行分组,那么该类也可能做得太多(再次违反SRP)。

以“代码气味”的思路来思考,#region块不是代码本身并没有气味,但相反,它们更像“ Febreze for code”,因为它们试图隐藏气味。虽然我过去曾大量使用它们,但是当您开始进行重构时,您会发现它们很少,因为它们最终没有隐藏太多。

#7 楼

这里的关键词是“明智的”。很难想象将区域放入方法内部是明智的情况。这很可能是代码隐藏和懒惰。但是,有充分的理由在自己的代码中到处都有一些区域。

如果有很多区域,我确实认为这是一种代码味道。区域通常暗示将来可能进行重构。许多地区意味着实际上没有人接受过提示。

明智地使用它们,它们在具有多个方法的单个类的结构与每个仅具有几个方法的多个类的结构之间提供了良好的中间立场。当一个类开始将其重构为多个类但还不完全重构时,它们最有用。通过将相关方法分组在一起,如果它们继续增加,我以后可以轻松地将一组相关方法提取到自己的类中。例如,如果我有一个接近500行代码的类,那么在一个区域中使用总共收集200行代码的方法集可能以某种方式进行重构-而在另一个区域中使用100行代码方法也可能是一个很好的目标。

我喜欢使用区域的另一种方法是减少重构大型方法的负面影响之一:读者可以使用许多小型,简洁,易于重用的方法滚动浏览以找到另一种几乎不相关的方法。区域可能是一种为读者提供元封装方法及其帮助程序的好方法,因此,使用该类不同方面的人员可以将它们折叠起来并迅速关闭该部分代码。当然,这仅在您的区域组织得很好并且本质上被用作记录代码的另一种方法时有效。

通常,与不使用区域相比,我发现区域可以帮助我保持井井有条,帮助“编写文档”我的代码,并帮助我更快地找到要重构的地方。

#8 楼

我主要使用CRUD服务器类的区域来组织各种类型的操作。即使那样,我也很乐意没有它们。

如果广泛使用,它会发出危险信号。我会寻找那些责任太大的类。

根据我的经验,一个有数百行代码的方法绝对是一种味道。

#9 楼

我的经验法则是:如果文件中有5个以上的区域,这是一种代码味道

即,可以很好地描述字段,方法,属性和构造函数,但是如果您要开始将其他所有方法都包装在自己的区域中是严重错误的

..是的,我经常在很多项目中,这通常是因为编码标准不佳,代码生成或两者。不得不切换Visual Studio中的所有轮廓来获得代码的很好概览,这很快就变得很老了。

#10 楼

区域已得到使用

在Windows窗体应用程序之前,我曾亲自将它们用于“手工编码”界面事件。

但是,在我的工作中,我们使用代码生成器来处理SQL,并且它自动使用区域来整理其选择,更新,删除等类型的方法。

因此,尽管我不经常使用它们,但它们对于删除大块代码非常合适。

评论


我使用过类似的代码生成器,并且更喜欢使用局部类来删除生成的代码。

– Craig
2011年3月1日,1:11

我们这样做,区域位于生成的代码内部,以使其更易于阅读或调试(如果需要)。

–肯
2011年3月1日在1:24

#11 楼

如果您在代码中包含区域,那么您肯定会遇到问题(除非生成代码的情况。)将区域放入代码中基本上是在说“重构此”。

但是,还有其他情况。我回想了一段时间:一个有几千个预先计算的项目的表。这是对几何的描述,没有表格中的错误,永远不会有机会查看它。当然,我可以从资源或类似资源中获取数据,但是这将排除使用编译器来使其易于阅读的可能性。

评论


对于存储在单独文件中的局部类,或者使用HardcodedDataSource实现注入的IMyDataSource,这是一个更好的用例。

–布莱恩·博特彻(Bryan Boettcher)
17年6月2日在20:05

#12 楼

在最近的项目中,有一种1700行方法,其中嵌入了多个区域。有趣的是,这些区域划分了在该方法内正在执行的不同操作。我能够在每个区域上执行重构->提取方法,而不会影响代码的功能。

通常,用于隐藏样板代码的区域很有用。我建议不要使用区域来隐藏属性,字段等,因为如果它们在类中工作时太笨拙而无法查看,则可能表明该类应该进一步分解。但是作为一个硬规则,如果要在方法中放置区域,最好提取另一种方法来解释正在发生的事情,而不是将该块包装在区域中。

#13 楼

可以在质量好的代码中使用区域吗?大概。我敢打赌,在很多情况下,它们都是如此。但是,我的个人经历使我非常怀疑-我看到几乎完全被滥用的区域。我会说我很疲惫,但仍然很乐观。

我可以将迄今为止看到的使用区域的代码大致分为三类:


因数分解的代码:
我见过的大多数代码都将区域用作穷人的因式分解工具。例如,某个类已经发展到可以针对不同目的进行专门化的程度,则可以将其拆分为不同的区域,每个目的一个区域。
使用错误的库,有时使用错误的语言编写的代码,对于问题域
通常,当程序员没有为问题域使用正确的库集时,您会看到代码变得非常冗长-带有许多实际上并不属于的小辅助函数(它们可能属于他们自己的图书馆。)
由学生或应届毕业生编写的代码。某些程序和课程似乎试图通过各种奇怪目的将区域灌输给学生。您会看到区域将源代码乱七八糟,直到区域标记与代码行的比率在1:5或更差的范围内。


#14 楼

我会说这是一种“代码异味”。

反模式通常是软件中的基本结构问题,而区域本身只会在编辑器中造成令人讨厌的行为。使用区域实际上并没有本质上的坏处,但是经常使用它们,尤其是隐藏代码块可以表明在其他地方还存在其他独立的较大问题。

评论


@安德鲁·格林(Andrew Grimm):是的

–whatsisname
2011年3月1日下午4:22

#15 楼

我仅将区域用于一件事(至少我无法想到使用它们的其他地方):将方法的单元测试分组。

我通常每个类都有一个测试类,然后进行分组单元通过使用具有方法名称的区域来测试每种方法。不知道这是代码的味道还是什么,但是由于基本思想是单元测试不需要更改,除非它们因为代码中的某些内容发生更改而中断,这使我更容易找到特定方法的所有测试很快。

我过去可能曾经使用区域来组织代码,但是我不记得上一次这样做了。虽然我坚持在单元测试课程中学习我的区域。

评论


您是否曾经测试过多种方法?

– Marcie
2011-3-2在3:09

我不太了解这个问题或您的目标是什么。答案是:不,单元测试始终仅针对一种方法,或者仅针对一种方法的某个方面。

–安妮·舒斯勒(Anne Schuessler)
2011年3月2日在9:02

#16 楼

我相信这是一种反模式,并且坦率地认为应该将其消除。但是,如果您处于在标准位置工作的不幸境地,则Visual Studio提供了一个很棒的工具来最小化您每次看到一个区域时想要呕吐的数量。I Hate #Regions

这个插件将使该区域的字体大小很小。它们也将被扩展,因此您无需点击ctr + m + l即可打开所有区域。它不能解决这种形式的代码癌症,但确实可以忍受。

#17 楼

我使用区域来包含可见性和成员类型的每种组合。因此,所有私有函数都进入一个区域等。

我这样做的原因不是,所以我可以折叠代码。这是因为我编写了脚本编辑器,因此可以插入对代理的引用:

#region "private_static_members"
 /// <summary>
 /// cache for LauncherProxy
 /// </summary>
private static LauncherProxy _launcherProxy;
#endregion

#region "protected_const_properties"
protected LauncherProxy LauncherProxy{
  get{
    if(_launcherProxy==null) {
      if (!God.Iam.HasProxy(LauncherProxy.NAME)) {
        God.Iam.RegisterProxy(new LauncherProxy());
      }
      _launcherProxy=God.Iam.Proxy(LauncherProxy.NAME) as LauncherProxy;
    }
    return _launcherProxy;
  }
}
#endregion


插入代码,并将各部分整齐地塞入正确的区域。在这种情况下,宏将分析我的项目,给我一个代理列表框,并为我想要的代码注入代码。我的光标甚至都没有动。

在学习C#的开始,我曾考虑过使用区域来保持共同性,但这是一个命中注定的命题,因为它不是一对一的始终保持一种关系。谁想烦恼两个地区使用的成员,或者甚至开始按这些术语分解事物。

唯一的另一种类型的隔离是方法-我将方法分解为Commands,Functions,和Handlers,所以我会有一个公共,私有等命令区域,等等。

这给了我粒度,但是我可以依靠的是一致的,明确的粒度。

评论


当我获得125分的低票时,-1。您正在添加不需要的代码行。为什么为什么为什么要在属性周围放置一个区域... if(God.Iam.AbusingRegions()== true)myName =“ Mark”

–DeadlyChambers
2014年8月4日在22:47

@DeadlyChambers原因在第二段中说明-我正在使用编辑器宏将常见的代码模式注入文件中,这些区域有助于保持文件的结构,以便对相似项进行分组。我不是在单个属性周围放置区域,而是所有属性都取决于其属性“ protected_const_properties”落入指定区域。您看过帖子吗?

–马克
2014年8月5日上午11:20

您可能可以将其重构为:受保护的LauncherProxy LauncherProxy => God.Iam.GetOrAddProxy (ref _launcherProxy);因此,您现在不需要区域了。 _launcherProxy也可以重命名为_launcherProxyCache,因此您不需要区域或在其中注释。

– Aeroson
17年1月25日在8:37



#18 楼

区域是预处理器表达式-换句话说,它们被视为注释,基本上被编译器忽略。它们纯粹是Visual Studio中使用的可视工具。因此,#region并不是真正的代码味道,因为它不是代码。代码气味是800行方法,其中嵌入了许多不同的职责,因此,如果您在一种方法中看到10个区域,则可能是它用来隐藏代码气味。话虽如此,我已经看到他们非常有效地使用了它,使一堂课更加令人赏心悦目,并且易于导航-在一个编写得很好且结构化的课中也是如此!

#19 楼

区域是一个不错的组织构想,但是没有考虑到某些开发人员倾向于对所有内容进行过度分类的趋势,按照大多数现代OOP惯例,区域通常是不必要的...在某种意义上,它们是“气​​味”,因为使用它们常常表示您的类/方法太大,应该进行重构,因为您可能违反了SOLID原则的“ S” ...但是,就像任何气味一样,它不一定表示有问题。

区域在功能代码中而不是在面向对象的代码IMO中具有更多的用途,在IMO中,有很长的顺序数据功能可以分解,但是有些时候我亲自在c#中使用它们,并且他们几乎总是专注于您不需要/不想看的代码。对我来说,这些通常是用于NPoco或其变体的代码库中的原始SQL字符串常量。除非您真正关心数据是如何通过您的ORM填充POCO对象的,否则这些都是毫无意义的……而且,如果您确实关心,请扩大区域和BAM!超过150行的复杂SQL查询为您带来观赏乐趣。