当前位置:  开发笔记 > 编程语言 > 正文

如何将ICollection <T>转换为IReadOnlyCollection <T>?

如何解决《如何将ICollection<T>转换为IReadOnlyCollection<T>?》经验,为你挑选了2个好方法。

当我ICollection在C#中有一个变量时,我无法将它传递给期望IReadOnlyCollection:

public void Foo()
{
  ICollection data = new List();
  // Bar(data); // Not allowed: Cannot implicitly cast ICollection to IReadOnlyCollection
  Bar(data.ToList()); // Works, since List implements IReadOnlyCollection
}

public void Bar(IReadOnlyCollection data)
{
  if (data.Count == 1) { /* ... */ }
  // ...
}

显然问题是ICollection不继承IReadOnlyCollection- 但为什么?ICollection应该是完整的功能集IReadOnlyCollection以及修改集合的函数.

传递参数的最佳解决方案是什么?

一方面,因为我不想改变集合Bar,只需要计数并迭代集合,我想要一个IReadOnlyCollection.

另一方面,每次调用该函数时,我都不想创建新的列表对象.



1> Ivan Stoev..:

没有标准的解决方案AFAIK,但是像这样制作自己的并不难

public static class MyExtensions
{
    public static IReadOnlyCollection AsReadOnly(this ICollection source)
    {
        if (source == null) throw new ArgumentNullException("source");
        return source as IReadOnlyCollection ?? new ReadOnlyCollectionAdapter(source);
    }

    sealed class ReadOnlyCollectionAdapter : IReadOnlyCollection
    {
        readonly ICollection source;
        public ReadOnlyCollectionAdapter(ICollection source) => this.source = source;
        public int Count => source.Count;
        public IEnumerator GetEnumerator() => source.GetEnumerator();
        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
    }
}

然后如下使用

Bar(data.AsReadOnly());


您可能认为这将成为标准的一部分。

2> Servy..:

你可以非常简单地创建一个组成一个ICollectionwhile实现的类IReadOnlyCollection.您还可以创建一个扩展方法来进行包装(从而允许进行泛型类型推断):

public class ReadOnlyCollectionWrapper : IReadOnlyCollection
{
    private ICollection collection;
    public ReadOnlyCollectionWrapper(ICollection collection)
    {
        this.collection = collection;
    }

    public int Count
    {
        get { return collection.Count; }
    }

    public IEnumerator GetEnumerator()
    {
        return collection.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return collection.GetEnumerator();
    }
}

public static class ReadOnlyCollectionWrapper
{
    public static IReadOnlyCollection AsReadOnly(this ICollection collection)
    {
        return new ReadOnlyCollectionWrapper(collection);
    }
}

推荐阅读
echo7111436
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有