用好C#中的#region指令 实现良好的代码组织

开发 后端
在这里我们将介绍的是C#中的#region指令,用好该指令可以一些有关联的代码组织在一起,然后折叠起来。这样你就在一个函数中看不到很长很长的代码段。

这篇文章我将不会去介绍如何使用#region指令。因为每个C#开发人员都应该见过和使用过#region指令的。这篇文章将讨论如何在代码中正确的使用它。使用#region就是将一些有关联的代码组织在一起,然后折叠起来。这样你就在一个函数中看不到很长很长的代码段。例如:

  1. public void DoSomething()  
  2. {    
  3. bool shouldIDoSomething;     
  4. #region Decide if I should do something   
  5. if(needToDoSomething && haventDoneSomethingThisDay)  
  6. shouldIDoSomething = true;   
  7.  else    
  8. {  
  9. // do some other logic to decide and 
  10. set shouldIDoSomething to some value  
  11.   }    
  12. #endregion     
  13. if(shouldIDoSomething)    
  14. {done++;  }} 

当然这段代码很简单。在实际项目中,你可能看到上百行甚至更多的代码在一个#region中。如果把它折叠起来。看起来就会很整洁。是吧?

  1. public void DoSomething()  
  2. {    
  3. bool shouldIDoSomething;     
  4. [Decide if I should do something]     
  5. if(shouldIDoSomething)    
  6. {done++;    
  7. }} 

我们只是把一些代码和一些变量组合起来放在#region中。如果你在仔细想想,其实我们相当与创建了一个新的函数,只是将这些方法内置到当前方法中。一个函数只做单一的一件事情,这是Clean Code这本书的一个原则。为什么我们不把它提取为一个方法呢,这样一来,一个函数就只做一件事情了。

  1. public void DoSomething(){    
  2. if(ShouldIDoSomething())   
  3.  {done++;  }}   
  4. private bool ShouldIDoSomething(){    
  5. if(needToDoSomething && haventDoneSomethingThisDay)  
  6. shouldIDoSomething = true;    
  7. else   
  8.  {  
  9. // do some other logic to decide   
  10. and set shouldIDoSomething to some value  }} 

这样看起来就清楚很多,因为我们降低了之前的DoSomething函数的复杂度。两个函数可以分开测试,确保没有逻辑错误。
小段总结1:  #region 不适合在大方法中使用,当你在一个方法中使用#region 的时候,停下来想想你刚刚写了什么代码?大多数时候,你可以将这些代码段独立成一个函数。

看看下面这段非常漂亮的代码:

  1. #region Get Customer   
  2. public void GetCustomer(){    
  3. // code to get the customer}   
  4. #endregion   
  5. #region Save Customer   
  6. public void SaveCustomer(){    
  7. // code to save the customer}   
  8. #endregion 

将它折叠之后,变成下面这样:

  1. [Get Customer] [Save Customer] 

这样做很容易阅读吗?这样做的目的是什么,我不明白?代码折叠就会变得更好?我觉得这样做只会让代码更难以阅读,因为你每次要看region中的代码,你都要展开一次。

小段总结2:不要因为你能,你就使用#region 。

再看下面这个例子

  1. public class PriceCalculator{    
  2. public decimal CalculatePrice()    
  3. {decimal price = 100m;decimal discount = CalculateDiscount();  
  4. return price * (1m - discount));   
  5.  }     
  6. #region Discount Calculation     
  7. private void CalculateDiscount()    
  8. {decimal discount = 0m;   
  9. if(CanApplyDiscount())    
  10. discount = 0.05m;   
  11. return discount;   
  12.  }     
  13. private void CanApplyDiscount()  {  
  14. // some logic, other method calls  }     
  15. // some other discount calculation methods  ...     
  16. #endregion} 

如果你将这个例子和本文中的***个例子做下比较,你可能会看到它们的共同点。他们是相同的,不过一个是在类中,一个是在函数中,层级不同而已。这里在提一个原则:单一职责原则,一个类应该只有一个职责。看上面的类,你可以很容易看出它有两个职责:价格计算和折扣计算。折扣计算的方法被放到一个#region中。同样,可以将它们提取出来做为一个新类。

小段总结3:可以将一组相关的函数提取到一个职责单一的新类中。

 那我们到底怎么使用 #region 呢。将东西用它来分组,它是非常有用的。在我写的类中或多或少有几个regions,用来对类中不同的结构进行分组。比如: fields, properties, methods, events, types等。如果你打开我写的类文件,你会看到结构如下:

  1. public class SomeClass{  
  2. [Events]  
  3. [Fields]  
  4. [Properties]   
  5. [Methods]} 

总的来说:我将region看成能控制阅读源代码的复杂度的一种方式。因为你可以将一些相关的代码放在一个区域(region)里面。但是,这不是随便就创建的新的方法或者新类的借口。其实Region并不能消除复杂度,它只是在你阅读代码的时候,隐藏了部分代码。你必须通过写出小巧,清晰,重点突出的方法和类,才能控制代码的复杂度。当你做到这些的时候,你甚至会发现region是不必要的。

原文标题:如何正确地使用#region指令

链接:http://www.cnblogs.com/zhuqil/archive/2010/09/07/about-region-preprocessor-directive.html

【编辑推荐】

 

  1. C#模式窗体中的按钮操作
  2. C#模式窗体操作详解
  3. C#窗体继承原理以及实现浅析
  4. C#窗体关闭事件的重载实现浅析
  5. C#窗体位置与大小设置详解

 

责任编辑:彭凡 来源: 博客园
相关推荐

2011-07-06 10:47:52

C#using

2023-11-23 13:07:18

代码Golang

2009-09-02 17:24:44

C#关机代码

2009-08-18 13:35:06

C#枚举文件

2009-05-26 16:33:48

PythonC#Run As

2021-09-13 07:00:01

C# .NET 缓存

2009-08-12 18:29:06

C#读取TXT文件

2015-07-28 10:06:03

C#内部实现剖析

2009-08-12 14:10:37

asp.net分页代码

2024-07-22 14:34:20

简单工厂模式C#

2009-08-19 15:38:59

C#代码

2009-03-12 13:49:30

DataTemplatWPFC#

2009-08-14 00:30:09

C#条件编译指令

2009-05-13 11:50:17

C#多继承接口

2009-08-04 09:22:26

C#工厂模式

2009-08-03 16:35:30

C#日期比较

2009-09-01 18:29:10

C#继承C#多态

2009-08-26 09:54:45

C#打印预览C#打印

2011-07-06 09:44:34

C#

2011-07-06 09:46:56

C#
点赞
收藏

51CTO技术栈公众号