【问题标题】:Collection as Collection of base type c# 2.0集合作为基本类型的集合 c# 2.0
【发布时间】:2009-12-08 23:30:09
【问题描述】:

我知道Passing a generic collection of objects to a method that requires a collection of the base type

我如何在没有 .Cast 的 .Net 2.0 中做到这一点???

它必须是引用相等,即列表的副本不会这样做。

要重新迭代 - 我无法返回 列表 - 它必须是相同的列表

【问题讨论】:

  • Cast 运算符无论如何都不能满足您的要求。它不保留参考身份。

标签: c# collections


【解决方案1】:

你没有。

在 C# 2 和 3 中,不可能有引用相等和改变元素类型。

在 C# 4 中,您可以拥有引用相等性并改变元素类型;这种转换称为“协变”转换。协变转换仅在 IEnumerable<T> 上是合法的,不是IList<T>List<T> 上。只有当源 T 类型和目标 T 类型是引用类型时,协变转换才是合法的。简而言之:

List<Mammal> myMammals = whatever;
List<Animal> x0 = myMammals; // never legal
IEnumerable<Mammal> x1 = myMammals; // legal in C# 2, 3, 4
IEnumerable<Animal> x2 = myMammals; // legal in C# 4, not in C# 2 or 3
IEnumerable<Giraffe> x3 = myMammals; // never legal
IList<Mammal> x4 = myMammals; // legal in C# 2, 3, 4
IList<Animal> x5 = myMammals; // never legal
IList<Giraffe> x6 = myMammals; // never legal
List<int> myInts = whatever;
IEnumerable<int> x7 = myInts; // legal
IEnumerable<object> x8 = myInts; // never legal; int is not a reference type

【讨论】:

    【解决方案2】:

    埃里克是正确的。他应该是公认的答案。不过,我会再添加一个建议。如果它是您的集合(如您可以修改集合类),您可以实现 IEnumerable(Of WhatWhatBase),即使您的集合派生自 Collection(Of What)。

    事实上,你也可以实现 IList(OfwhateverBase)、ICollection(OfwhateverBase) 等 - 例如,如果你在 Add 方法中获得不兼容的类型,则会引发运行时异常。

    class GiraffeCollection : Collection<Giraffe>, IEnumerable<Animal> {
    
        IEnumerator<Animal> IEnumerable<Animal>.GetEnumerator() {
            foreach (Giraffe item in this) {
                yield return item;
            }
        }
    
    }
    

    【讨论】:

    • 确实,我们经常看到这种模式用于解决缺乏接口协方差的问题。幸运的是,一旦我们在语言和基类库中获得真正的接口协变,它就会开始消失。
    【解决方案3】:

    你想要:

    List<T>.ConvertAll()
    

    See here 了解更多信息。

    【讨论】:

    • 这不满足列表具有引用相等性的规定要求。
    猜你喜欢
    • 2019-12-05
    • 1970-01-01
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 2021-09-29
    • 1970-01-01
    • 2023-03-20
    • 2021-11-14
    相关资源
    最近更新 更多