IList in interface,List in implementation

时间:2013-07-25 09:26:20

标签: c# list interface abstraction

在我的界面中,通常有一个IList<ISomeType>来表示List类型的成员 并且说我希望实现支持Add方法。

但是在接口实现中,有一个

IList<ISomeType> = new List<ISomeType>()

每次我使用List时,我都要演员,例如

(this.MyList as List<IMyType>).AddRange(someType.ToList());

有更好的方法吗?如何避免这种演员?

- 编辑以询问更多信息 -

有没有一个小的linq表达式来解决这个问题而不是扩展方法?

IList<string> list = new List<string>();
var items = new[] { "1", "2", "3" };
items.ToList().ForEach(x => list.Add(x));

但这看起来并不是很直接,因为它颠覆了正在做的事情。 (操作在要添加的项目上,而不在列表中。)

还有什么比这更好的?可以在列表上做些什么?

2 个答案:

答案 0 :(得分:5)

AddRange不是IList上的方法,但是Add is,因此您可以轻松制作扩展方法:

public static void AddRange<T>(this IList<T> list, IEnumerable<T> values) {
    foreach(var value in values)
        list.Add(value);
}

您还可以在扩展方法中检查列表是否实际上是List的实例,在这种情况下您可以直接调用AddRange

答案 1 :(得分:0)

可以制作Martin建议的扩展方法,但这可能会破坏内容。

为什么人们使用界面?表达公共合同。现在这个合同是在.NET BCL框架中。如果您将代码公开给外部参与方,则还必须公开扩展方法,并确保人们在扩展名所在的文件中添加using语句。这可能会导致编译时错误(AddRange 中可用“No IList<T>方法。)

此外,扩展方法制动Liskov substitution原则(用基类型替换超类型)。

因此,如果您只在方法中使用List<T>,则可以轻松地将IList<T>更改为List<T>