如何创建无参数索引器

时间:2014-03-06 11:55:53

标签: c# properties

我可能已将自己编入角落,但我希望有一个简单的方法。

我的逻辑层是一个静态单例实例,它具有许多用于访问各个子逻辑层的属性。其中大部分用于单元测试,以允许注入自定义存储库,并且非常适合这种情况。然而,每个子实例的锅炉板代码非常重复,我希望有一种方法可以简化它。

下面是一个非常简单的示例,用于说明我已经设法获得了多远以及我遇到了什么。一种方法是使用子逻辑类包装器上的索引器来获取子逻辑,这非常奇怪。另一种方法是使用随机字母作为子逻辑类包装器的属性来获取子逻辑。这读得稍微好些,但仍然会对所有现有代码产生连锁反应。

这可以按照我想要的方式完成,或者我应该以完全不同的方式看待这一点。 抱歉示例的长度。我试图让它尽可能简单,同时仍然保持概念完整

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;
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您可以使用界面来解决您的问题: 1)使用List方法定义接口:

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()

List方法的实现将是:

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>>();

但这取决于你想要什么