用好C#中的#region指令 實現(xiàn)良好的代碼組織
這篇文章我將不會去介紹如何使用#region指令。因為每個C#開發(fā)人員都應該見過和使用過#region指令的。這篇文章將討論如何在代碼中正確的使用它。使用#region就是將一些有關(guān)聯(lián)的代碼組織在一起,然后折疊起來。這樣你就在一個函數(shù)中看不到很長很長的代碼段。例如:
- public void DoSomething()
- {
- bool shouldIDoSomething;
- #region Decide if I should do something
- if(needToDoSomething && haventDoneSomethingThisDay)
- shouldIDoSomething = true;
- else
- {
- // do some other logic to decide and
- set shouldIDoSomething to some value
- }
- #endregion
- if(shouldIDoSomething)
- {done++; }}
當然這段代碼很簡單。在實際項目中,你可能看到上百行甚至更多的代碼在一個#region中。如果把它折疊起來??雌饋砭蜁苷麧崱J前??
- public void DoSomething()
- {
- bool shouldIDoSomething;
- [Decide if I should do something]
- if(shouldIDoSomething)
- {done++;
- }}
我們只是把一些代碼和一些變量組合起來放在#region中。如果你在仔細想想,其實我們相當與創(chuàng)建了一個新的函數(shù),只是將這些方法內(nèi)置到當前方法中。一個函數(shù)只做單一的一件事情,這是Clean Code這本書的一個原則。為什么我們不把它提取為一個方法呢,這樣一來,一個函數(shù)就只做一件事情了。
- public void DoSomething(){
- if(ShouldIDoSomething())
- {done++; }}
- private bool ShouldIDoSomething(){
- if(needToDoSomething && haventDoneSomethingThisDay)
- shouldIDoSomething = true;
- else
- {
- // do some other logic to decide
- and set shouldIDoSomething to some value }}
這樣看起來就清楚很多,因為我們降低了之前的DoSomething函數(shù)的復雜度。兩個函數(shù)可以分開測試,確保沒有邏輯錯誤。
小段總結(jié)1: #region 不適合在大方法中使用,當你在一個方法中使用#region 的時候,停下來想想你剛剛寫了什么代碼?大多數(shù)時候,你可以將這些代碼段獨立成一個函數(shù)。
看看下面這段非常漂亮的代碼:
- #region Get Customer
- public void GetCustomer(){
- // code to get the customer}
- #endregion
- #region Save Customer
- public void SaveCustomer(){
- // code to save the customer}
- #endregion
將它折疊之后,變成下面這樣:
- [Get Customer] [Save Customer]
這樣做很容易閱讀嗎?這樣做的目的是什么,我不明白?代碼折疊就會變得更好?我覺得這樣做只會讓代碼更難以閱讀,因為你每次要看region中的代碼,你都要展開一次。
小段總結(jié)2:不要因為你能,你就使用#region 。
再看下面這個例子
- public class PriceCalculator{
- public decimal CalculatePrice()
- {decimal price = 100m;decimal discount = CalculateDiscount();
- return price * (1m - discount));
- }
- #region Discount Calculation
- private void CalculateDiscount()
- {decimal discount = 0m;
- if(CanApplyDiscount())
- discount = 0.05m;
- return discount;
- }
- private void CanApplyDiscount() {
- // some logic, other method calls }
- // some other discount calculation methods ...
- #endregion}
如果你將這個例子和本文中的***個例子做下比較,你可能會看到它們的共同點。他們是相同的,不過一個是在類中,一個是在函數(shù)中,層級不同而已。這里在提一個原則:單一職責原則,一個類應該只有一個職責??瓷厦娴念?,你可以很容易看出它有兩個職責:價格計算和折扣計算。折扣計算的方法被放到一個#region中。同樣,可以將它們提取出來做為一個新類。
小段總結(jié)3:可以將一組相關(guān)的函數(shù)提取到一個職責單一的新類中。
那我們到底怎么使用 #region 呢。將東西用它來分組,它是非常有用的。在我寫的類中或多或少有幾個regions,用來對類中不同的結(jié)構(gòu)進行分組。比如: fields, properties, methods, events, types等。如果你打開我寫的類文件,你會看到結(jié)構(gòu)如下:
- public class SomeClass{
- [Events]
- [Fields]
- [Properties]
- [Methods]}
總的來說:我將region看成能控制閱讀源代碼的復雜度的一種方式。因為你可以將一些相關(guān)的代碼放在一個區(qū)域(region)里面。但是,這不是隨便就創(chuàng)建的新的方法或者新類的借口。其實Region并不能消除復雜度,它只是在你閱讀代碼的時候,隱藏了部分代碼。你必須通過寫出小巧,清晰,重點突出的方法和類,才能控制代碼的復雜度。當你做到這些的時候,你甚至會發(fā)現(xiàn)region是不必要的。
原文標題:如何正確地使用#region指令
鏈接:http://www.cnblogs.com/zhuqil/archive/2010/09/07/about-region-preprocessor-directive.html
【編輯推薦】