IEnumerable如何将项目添加到列表

时间:2018-12-11 10:21:57

标签: c#

我有如下所示的界面。问题出在AddLogger()方法中,我不能仅使用Loggers.Add(logger);

public interface INotificationFactory
{
    IEnumerable<ILogger> Loggers
    {
        get;
        set;
    }
    void AddLogger(ILogger logger);
    void DoLog(EMsgType msgType, string msg);
    IEnumerable<ILogger> GetLoggers();
}

接口实现:

public class NotificationFactory : INotificationFactory
{
    public IEnumerable<ILogger> Loggers  // read-write instance property
    { get; set; }

    public NotificationFactory()
    {
        Loggers = new List<ILogger>();
    }


    public void AddLogger(ILogger logger)
    {
        Loggers.Add(logger);
    }

    public void DoLog(EMsgType msgType, string msg)
    {
        foreach (var logger in Loggers)
        {
            logger.Write(msgType, msg);
        }
    }

    public IEnumerable<ILogger> GetLoggers()
    {
        return Loggers;
    }
}

1 个答案:

答案 0 :(得分:0)

我建议重新设计:

接口:

public interface INotificationFactory
{
    IEnumerable<ILogger> Loggers
    {
       get;
       set; // <- Remove it if it's possible
    }

    void AddLogger(ILogger logger);
    void DoLog(EMsgType msgType, string msg);

    // Remove it if it's possible: Loggers is enough
    IEnumerable<ILogger> GetLoggers();  
}

实施:

public class NotificationFactory : INotificationFactory
{
    // backing field: List<T> is by far more convenient than IEnumerable<T>
    private List<ILogger> m_Loggers = new List<ILogger>();  

    // Read-only: we don't want someone change the collection and removing items from it:
    public IReadOnlyList<ILogger> Loggers { 
        get {
            return m_Loggers;
        } 
    }

    IEnumerable<ILogger> INotificationFactory.Loggers {
        get {
            return m_Loggers;
        } 
        set {
            throw new NotSupportedException("Don't try to assign the collection"); 
        } 
    }

    // The only way to add an item - logger - is this direct call  
    public void AddLogger(ILogger logger)
    {
        if (null == logger)
            throw new ArgumentNullException(nameof(logger));

        // Just adding a logger - nothing to write home about
        m_Loggers.Add(logger);
    }

    public void DoLog(EMsgType msgType, string msg)
    {
        foreach (var logger in m_Loggers)
        {
            logger.Write(msgType, msg);
        }
    }

    //TODO: Do you want it? Loggers property seems to be enough
    IEnumerable<ILogger> INotificationFactory.GetLoggers()
    {
        return m_Loggers;
    }
}