IEnumerable如何向列表添加项目

12 浏览
0 Comments

IEnumerable如何向列表添加项目

我有以下所示的接口。问题出在AddLogger()方法上,我不能仅使用Loggers.Add(logger);\n

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

\n接口实现:\n

public class NotificationFactory : INotificationFactory
{
    public IEnumerable Loggers  // 可读写的实例属性
    { get; set; }
    public NotificationFactory()
    {
        Loggers = new List();
    }
    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 GetLoggers()
    {
        return Loggers;
    }
}

0
0 Comments

在这段代码中,问题的出现是因为作者在接口中使用了IEnumerable作为日志记录器列表的返回类型,而不是直接使用List。这可能是因为IEnumerable可以转换为不同的集合类型,如List/Array等,因此作者选择了IEnumerable作为返回类型。然而,大多数开发人员在他们的环境中使用IEnumerable而不是List,可能是因为接口的设计更加通用,可以适用于不同类型的集合。

解决这个问题的方法是将接口中的IEnumerable改为List,并在实现类中使用List作为内部字段。同时,为了防止外部修改集合并删除其中的项,可以将Loggers属性改为只读的IReadOnlyList类型,并在AddLogger方法中添加日志记录器。

另外,作者建议将返回的集合类型改为IReadOnlyList而不是IEnumerable,这样可以提供更多的操作,如索引器和计数器。然而,这也会带来一些额外的时间和内存开销。

最后,关于为什么开发人员经常在接口中使用IEnumerable而不是List,可能是因为接口是更通用的契约,并且可以以不同的方式实现。例如,从数据库中加载日志记录器时,可能不希望直接返回一个列表,而是通过IEnumerable提供一个枚举的方式。同时,通过使用接口,可以更好地支持测试和依赖注入等开发模式。

因此,作者建议在接口中使用IEnumerable作为返回类型,并在实现类中提供更具体的集合类型作为扩展服务。接口仅提供最基本的功能,而实现类可以提供更多的操作和特性。

0