为什么我可以将一个数组传递给接受 IList 的方法,但尝试使用此接口时却出现错误(数组显然不支持 Add())

using System.Collections.Generic;
                    
public class Program
{
    public static void Main()
    {
        string[] thisIsArray = ["A", "B"];
        IsThisBug(thisIsArray);
    }
    
    public static void IsThisBug(IList<string> array) {
        array.Add("Hello");
    }
}

1

  • 2
    这是微软对里氏替换原则最令人震惊的违反之一(至少从技术上讲 – 有一个属性IsReadOnly确实可以缓解一点;但我仍然不喜欢这种设计)。


    – 



最佳答案
3

支持这样的接口通常很有用– 即使不是每个方法都可以完全实现;例如,与限制性更强的 不同ICollectionIList还添加了this[int index] {get;set;}数组可以支持的索引器 – 因此,如果数组实现ICollection,则会丢失一些其他有用的功能。它还具有 属性.IsFixedSize,这是您在尝试使用 之前应该检查的.Add(...),因此NotSupportedException并不奇怪。

8

  • IsFixedSize?应该是 IsReadOnly。不应该改变太多,但 IsFixedSize 听起来很间接。


    – 


  • 我认为你的意思是使用IsReadOnly而不是IsFixedSize


    – 

  • 通用 IList<T> 上没有 IsFixedSize 属性,这是我使用 IList<T> 的正确方法吗?IList<string> x = [“A”]; IList y = (IList)x; if (!y.IsFixedSize) { x.Add(“hmm”); } ((抱歉,不知道如何在此处的注释中放置代码片段…))


    – 


  • @Ralf(回应现已删除的评论)不,IList<T>没有实现;许多实现IList的类型也实现了,但这不是完全相同的语句;是的,在这种情况下存在一些可发现性的差距 IList<T>IList


    – 


  • 1
    @Demo 用于注释中的代码格式:` 反引号 – 即 `foo` 是foo


    – 


这不是一个错误, Array,但是某些操作

Array确实实现了,IList除了它特别引发了一个异常,Add你可以在