在習慣了使用基於介面的編程之後,經常會遇到這樣的問題,比如,B組件需要使用實現了IA介面的A組件,但是如果在沒有A組件的情況下B組件也可以正常工作,像這樣: public interface IA
{
void DoWork1() ;
void DoWork2() ;
}
public class B :IB
{
private IA theA ;
public B(IA a)
{
this.theA = a ;
}
public void DoJob()
{
//
if(this.theA != null)
{
this.theA.DoWork1() ;
}
}
public void DoOtherJob()
{
//
if(this.theA != null)
{
this.theA.DoWork2() ;
}
}
}
可以看到很多地方都要用到if(this.theA != null)進行條件判斷,如果某個地方露掉了這樣的判斷,運行時可能就會拋出“引用為空白”的異常。有沒有辦法來徹底避免類似的條件判斷了?有,那就是EmptyClass的目的。EmptyClass實現了比如上述的IA介面,但是EmptyClass什麼都不做,即EmptyClass完全由VS.NET的智能感知自動產生(聲明EmptyClass時,在寫完介面名後按TAB鍵)。
我們看看自動產生的IA對應的EmptyClass: public class EmptyA :IA
{
#region IA 成員
public void DoWork1()
{
// TODO: 添加 EmptyA.DoWork1 實現
}
public void DoWork2()
{
// TODO: 添加 EmptyA.DoWork2 實現
}
#endregion
}
現在就可以在B中來避免前面的條件判斷了: public class B :IB
{
private IA theA ;
public B(IA a)
{
this.theA = a ;
// 如果引用為空白,則賦值什麼都不做的EmptyClass
if(this.theA == null)
{
this.theA = new EmptyA() ;
}
}
public void DoJob()
{
//
this.theA.DoWork1() ; // 不在需要條件判斷!!!!!!!!
}
public void DoOtherJob()
{
//
this.theA.DoWork1() ;
}
}
這個簡單的小技巧,你一定已經學會了:)
在當一個組件對另一個組件的引用可以為空白的時候,EmptyClass的執行個體就可以作為這個引用的預設值,這樣不僅沒有犧牲效能(空方法調用與條件判斷的開銷差不多),而且使得我們的代碼更漂亮、更容易閱讀和維護。