2014-03-06 34 views
-1

我可能已將自己編碼到了一個角落,但我希望有一個簡單的方法。如何創建無參數索引器

我的邏輯層是一個靜態單例實例,具有訪問各個子邏輯層的許多屬性。其中大部分是爲了進行單元測試而設置的,以允許注入定製存儲庫,並且對此非常適用。然而,每個子實例的鍋爐代碼是非常重複的,我期望有一種方法來簡化它。

下面是一個非常簡單的示例,用於說明我設法取得了多少以及卡住的位置。有效的方法之一是使用子邏輯類包裝器上的索引器來訪問子邏輯,該子邏輯非常奇怪。另一種方法是使用一個隨機字母作爲子邏輯類包裝器上的一個屬性,以達到子邏輯。這讀起來稍微好一些,但對所有現有代碼仍然有連鎖反應。

這可以按我想要的方式完成,或者我應該以完全不同的方式來看待它。 道歉的例子的長度。我試圖使它儘可能簡單,同時仍保持概念完整

class Program 
{ 
    static void Main(string[] args) 
    { 
     var logic = new Logic(); 
     // old usage (desired) 
     var abcs_1 = logic.ABCs_1.List(); 
     var defs_1 = logic.DEFs_1.List(); 
     // new usage (would like to keep old way) 
     var abcs_2 = logic.ABCs_2[0].List(); // <-- ugly 
     var defs_2 = logic.DEFs_2.d.List(); // <-- less ugly, but still not pretty 
     //var abcs_2 = logic.ABCs_2.List(); // <-- wanted 
     //var defs_2 = logic.DEFs_2.List(); // <-- wanted 
    } 
} 

public class ABC { } 

public class DEF { } 

public class ABCsLogicLayer 
{ 
    public List<ABC> List() { return null; } 
} 

public class DEFsLogicLayer 
{ 
    public List<DEF> List() { return null; } 
} 

public class Logic 
{ 
    #region New Code. Want to move towards this 
    public LogicLocker<ABCsLogicLayer> ABCs_2 = new LogicLocker<ABCsLogicLayer>(); 
    public LogicLocker<DEFsLogicLayer> DEFs_2 = new LogicLocker<DEFsLogicLayer>(); 
    #endregion 

    #region Old Code. Want to move away from this. 

    #region BuilerPlate for ABCs_1 
    private ABCsLogicLayer m_ABCs = null; 
    private readonly object m_ABCsLock = new object(); 
    public ABCsLogicLayer ABCs_1 
    { 
     get 
     { 
      lock (m_ABCsLock) 
      { 
       if (m_ABCs == null) 
       { 
        m_ABCs = new ABCsLogicLayer(); 
       } 
      } 
      return m_ABCs; 
     } 
     set 
     { 
      lock (m_ABCsLock) 
      { 
       m_ABCs = value; 
      } 
     } 
    } 
    #endregion 

    #region BuilerPlate for DEFs_1 
    private DEFsLogicLayer m_DEFs = null; 
    private readonly object m_DEFsLock = new object(); 
    public DEFsLogicLayer DEFs_1 
    { 
     get 
     { 
      lock (m_DEFsLock) 
      { 
       if (m_DEFs == null) 
       { 
        m_DEFs = new DEFsLogicLayer(); 
       } 
      } 
      return m_DEFs; 
     } 
     set 
     { 
      lock (m_DEFsLock) 
      { 
       m_DEFs = value; 
      } 
     } 
    } 
    #endregion 

    #endregion 
} 

public class LogicLocker<T> where T : class, new() 
{ 
    private T LogicLayer = null; 
    private readonly object LogicLayerLock = new object(); 

    public T this[int i] 
    { 
     get 
     { 
      lock (LogicLayerLock) 
      { 
       if (LogicLayer == null) 
       { 
        LogicLayer = new T(); 
       } 
      } 
      return LogicLayer; 
     } 
     set 
     { 
      lock (LogicLayerLock) 
      { 
       LogicLayer = value; 
      } 
     } 
    } 
    public T d 
    { 
     get 
     { 
      lock (LogicLayerLock) 
      { 
       if (LogicLayer == null) 
       { 
        LogicLayer = new T(); 
       } 
      } 
      return LogicLayer; 
     } 
     set 
     { 
      lock (LogicLayerLock) 
      { 
       LogicLayer = value; 
      } 
     } 
    } 
} 
+0

你是什麼意思的「無參數索引」?無參數索引器是屬性 –

+0

代碼中「醜陋」和「想要」之間的區別在哪裏? –

+0

@JeppeStigNielsen:謝謝。更新了代碼以反映我之後的情況。 –

回答

0

您可以使用界面解決您的問題: 1)定義接口列表方法:

public interface ILogicLayer<T> 
{ 
    List<T> List(); 
} 

2)你邏輯層類應該實現此接口:

public class ABCsLogicLayer:ILogicLayer<ABC> 

3)LogicLocker應該實現此界面,以及

public class LogicLocker<T,U> : ILogicLayer<U> where T : ILogicLayer<U>, new() 

列表方法的實現將是:

lock (LogicLayerLock) 
{ 
    if (LogicLayer == null) 
    { 
     LogicLayer = new T(); 
    } 
} 
return LogicLayer.List(); 

4)您將實例化邏輯更衣室在Logic

public LogicLocker<ABCsLogicLayer, ABC> ABCs_2 = new LogicLocker<ABCsLogicLayer,ABC>(); 
public LogicLocker<DEFsLogicLayer, DEF> DEFs_2 = new LogicLocker<DEFsLogicLayer, DEF>(); 

或更好的使其更仿製藥:

public LogicLocker<LogicLayer<ABC>> ABCs_2 = new LogicLocker<LogicLayer<ABC>>(); 

但它取決於你w螞蟻