首页 >后端开发 >C++ >如何在 .NET 集合中实现索引访问的协方差?

如何在 .NET 集合中实现索引访问的协方差?

Patricia Arquette
Patricia Arquette原创
2024-12-28 12:51:24174浏览

How Can I Achieve Covariance with Index Access in .NET Collections?

在 .NET 中利用协方差和索引访问支持

协方差使程序员能够将派生类视为其基类,而无需显式类型转换。但是,在 .NET 中,协变集合存在缺乏索引访问支持的限制。当尝试将特定类型的集合(例如,包含 Dog 对象的 List)转换为其基本类型的集合(例如,Animal)时,会出现此问题。

了解潜在问题

问题源于 List 实现了 ICollection,其中包含一个 Add 方法。向上转换为基于动物的 IList 将允许不加区别地添加任何类型的动物,从而违反原始集合的类型限制。

具有索引支持的协变集合

在 .NET 4.5 和后来:

  • IReadOnlyListIReadOnlyCollection 都是协变的。
  • List ;和 ReadOnlyCollection实现这些接口,提供一个仅获取索引器,能够在不违反协方差原则的情况下检索元素。

对于早期 .NET 版本:

  • 协方差早期 .NET 中不提供索引支持
  • 自定义包装方法: 一种解决方案是将原始集合包装在仅公开 IEnumerable 和获取索引器接口的自定义类中。此方法在维护索引访问功能的同时确保协方差。

实现:

以下 C# 代码演示了使用协方差扩展方法的自定义包装器方法:

public static class Covariance
{
    public static IIndexedEnumerable<T> AsCovariant<T>(this IList<T> tail)
    {
        return new CovariantList<T>(tail);
    }
    private class CovariantList<T> : IIndexedEnumerable<T>
    {
        private readonly IList<T> tail;
        public CovariantList(IList<T> tail)
        {
            this.tail = tail;
        }
        public T this[int index] { get { return tail[index]; } }
        public IEnumerator<T> GetEnumerator() { return tail.GetEnumerator();}
        IEnumerator IEnumerable.GetEnumerator() { return tail.GetEnumerator(); }
        public int Count { get { return tail.Count; } }
    }
}
public interface IIndexedEnumerable<out T> : IEnumerable<T>
{
    T this[int index] { get; }
    int Count { get; }
}

此扩展方法允许您创建具有索引支持的协变集合,如下所示例如:

List<Dog> dogs = new List<Dog>();

IIndexedEnumerable<Animal> animals = dogs.AsCovariant();

以上是如何在 .NET 集合中实现索引访问的协方差?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn