在.NET中,#region指令真的有用吗?

18

在维护大量使用 #region(无论是 C# 还是 VB.NET)的代码后,我认为这种结构只是程序员的一堆“繁琐工作”。将它们放入代码中需要付出努力,而且它们会使查找和阅读代码变得非常烦人。

那么,使用 #region 的好处是什么呢?为什么程序员要额外费心将其放入代码中呢?

让我相信它的价值吧!

17个回答

22

已经有人提出了类似的问题

但是...

我个人认为,这不再是一个问题。在早期版本的.NET中,它最初是用来隐藏WinForms中的生成代码的。随着部分类的引入,这种需求似乎消失了。在我的看法中,现在它被过度使用作为一种组织结构,没有任何编译器价值,只是为了IDE而存在。


哦,我应该删除我的问题吗? - jm.
在.NET中,空格也没有编译器值;)当然,您可以使用部分类来完成区域所做的事情,但是如何定义拆分位置呢? - Aaron Powell
1
@jm 不认为有必要删除这个问题。只要我们链接回原始来源就可以了。而且这是一个主观性问题,谈论起来还挺有趣的。 - Scott Saad
@Slace 你说得完全正确... 不确定在哪里划界。我想一个开始就是IDE将生成的代码分离到一个你真的不必查看的文件中。 - Scott Saad
从实用的角度来看,我发现它非常有用——它可以很好地将相关的方法或属性组织在一起,因此整个部分可以轻松地被忽略或检查,正如下面Russell Myers的评论所建议的那样。 - Mike

17
通常情况下,局部视图和#regions都被用来弥补糟糕的设计(例如类过于庞大或试图做太多事情)。
到目前为止,我使用#regions最好的方法是将许多不同类中看到的功能分组。例如,具有getter、setter、构造函数和支持字段的值对象。我可能会将这些想法分组到regions中。但是,代码是否更清晰或更易读取是一个主观问题。

14

http://www.rauchy.net/regionerate/ - 自动化地将您的代码区域化 ;)

我喜欢使用区域来对大型类中的各个部分进行分组,比如所有属性、所有常量等。我经常会折叠掉我当前不需要看到的代码,所以我很喜欢区域。

此外,我在实现接口时也发现区域非常有用,特别是多个接口的情况下。我可以将每个接口的方法、属性、事件等分组,这样一眼就能看出哪个方法属于哪个接口。


现在我们有了部分类,将每个接口拆分到自己的文件中有时更好。MyClass.cs 和 MyClass.IMyInterface.cs,这也使得当您在文件系统中搜索时它更加可见。 - Robert Paulson

6

我经常使用它们。像其他任何东西一样,它们可以被用作恶和善的工具,并且肯定会成为糟糕设计的标志,但它们可以被用来很好地组织代码。

#region Properties

#region Update Section

#region Accessors

当然你应该避免Jeff的例子

#Sweep under carpet

正如Jeff所指出的那样,我觉得奇怪的是它们是用于UI目的的编译器预处理命令。我相信VS团队可以用另一种方式做出同样有用的东西。


1
我想现在使用全新改版的基于WPF的编辑器VS 2010,我们将开始看到该领域各种新的改进。例如,我一直认为拥有“表格”或内联RTF用于文档注释会很棒。(但保存的文本只是纯文本。)现在有了新的编辑器,这是可行的。 - Josh

4
我们的Business Objects都有Regions - 我们很喜欢它们。
我们有以下内容; - Business Properties and Methods - Shared Methods - Constructors - Authorization - Data Access - Events
对于我们正在处理的业务对象类型(例如Subscriber等),还有其他一些。
对于许多类而言,regions只会妨碍我们 - 但对于我们的标准业务对象来说,它们节省了我们大量时间。这些Business Objects是代码生成的,因此它们非常一致。如果它们不是这样,那么可以更快地到达我想去的地方,而一致性使得易于找到彼此的内容。

3
我通常不使用代码区域,除了一种特定情况——依赖属性。尽管依赖属性在大多数方面都很好用,但它们的声明看起来很丑,很快就会让你的代码混乱不堪。(好像管理GUI代码已经够挑战了...) 我喜欢给该区域与CLR属性声明完全相同的名称(复制/粘贴到其中)。这样,当折叠时,您可以看到作用域、类型和名称,这正是95%的时间里您所关心的。
   #region public int ObjectDepthThreshold

    public int ObjectDepthThreshold
    {
        get { return (int)GetValue(ObjectDepthThresholdProperty); }
        set { SetValue(ObjectDepthThresholdProperty, value); }
    }

    public static readonly DependencyProperty ObjectDepthThresholdProperty = DependencyProperty.Register(
        "ObjectDepthThreshold",
        typeof(int),
        typeof(GotoXControls),
        new FrameworkPropertyMetadata((int)GotoXServiceState.OBJECT_DEPTH_THRESHOLD_DEFAULT,
            FrameworkPropertyMetadataOptions.AffectsRender,
            new PropertyChangedCallback(OnControlValueChanged)
        )
    );

    #endregion

当它折叠时,你只能看到:

public int ObjectDepthThreshold

如果我有多个依赖属性,我喜欢在下一行开始下一个 #region。这样你就可以将它们全部分组在类中,代码既紧凑又易读。
顺便说一下,如果你只想查看声明,请将鼠标悬停在上面即可。

2

我讨厌过度使用这些标签。我唯一觉得它们有用的地方就是隐藏那些你可能永远不想再看到的东西。但那些东西应该放在图书馆之类的地方。


2

继 Russell Myers 之前所说的话,如果你学会如何正确地重构代码(这是熟练开发人员必须学会的技能),实际上就不太需要使用区域了。

几周前我认为区域很棒,因为它们可以隐藏我的臃肿代码,但在练习我的代码技能后,我能够让它变得更加精简,现在我适合一个大小为7的类(未来应该制定一个这样的重构度量标准!:P)


2

我发现除了最简单的用法外,他们会混淆代码。我们项目中唯一推荐使用的是IDE使用的用法(接口实现和设计师代码)。

正确的工具应该用于正确的目的。代码应该被编写以显示意图和功能,而不是任意地分组东西。将东西组织成访问修饰符分组或其他分组似乎是不合逻辑的。我认为代码应该按照特定类的意义进行组织;毕竟,还有其他工具可以通过访问修饰符查看类成员。几乎所有其他用途的区域也是如此,有更好的方法。

例如,将属性、事件、常量或其他内容分组在一起并没有太多意义,因为如果按函数将这些内容分组,代码通常更易于维护(例如,使用常量的属性应该靠近该常量,而不是靠近其他无关的属性,仅仅因为它是一个属性)。


2

我经常使用它们来代替注释,对类的功能组进行排序,例如“配置公共接口”,“状态公共接口”,“内部处理”和“内部工作线程管理”。

通过使用键盘快捷键“折叠到定义”和“展开当前块”,我甚至可以轻松浏览更大的类。

不幸的是,C++的区域功能已经失效,微软似乎认为不需要修复。


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