【问题标题】:Why use IList over IEnumerable?为什么使用 IList 而不是 IEnumerable?
【发布时间】:2011-11-05 22:55:14
【问题描述】:

1) 我阅读了一些(通用)代码 sn-p 并看到一些使用IList<T> 的地方和一些使用IEnumerable 的地方。使用前者而不是后者的优点是什么?

2) isas 在 c# 中。 我知道is 进行类型检查,as 进行强制转换。 但究竟什么是铸造?强制数据到某个大小的对象? isas 什么时候不同?

【问题讨论】:

    标签: c# .net


    【解决方案1】:

    IList[<T>] 代表以下内容:

    • 可以迭代
    • 是有限的,已知大小
    • 可重复
    • 可以通过索引随机访问
    • 可以(可选,可检查)进行编辑:重新分配值、添加、删除等

    另一方面,IEnumerable 只能迭代。并非所有可以迭代的东西都是列表。例如:

    static IEnumerable<int> Get() {
        Random rand = new Random();
        while(true) yield return rand.Next();
    }
    

    ^^^ 是一个无限序列。它没有长度,不能被变异,不能被索引访问……但是,它可以被迭代:

    foreach(int i in Get().Take(200)) {
        Console.WriteLine(i);
    }
    

    is 执行返回 true/false... 的类型检查...即 objIList?是或否。

    as 执行“尝试执行此操作”类型检查;如果它失败,它返回null,或者如果它成功,它返回一个类型化的引用(等)。基本上,这是一个效率问题:

    if(obj is IList) {
        var list = (IList) obj;
        ...
    }
    

    效率低于:

    var list = obj as IList;
    if(list != null) {
        ...
    }
    

    如果obj 为空,它们的行为也会有所不同; is 抛出异常; as 返回null

    【讨论】:

    • 您实际测量过这两者的性能吗? IL 指令 isinst 虽然它的名称暗示它对应于实际上对应于 as 操作。在 IL 中没有操作。实际上在 IL 中是 obj as type != null blogs.msdn.com/b/ericlippert/archive/2010/09/16/…。所以选择应该是我想说的可读性
    • @RuneFS 我经常在 IL 中编写代码,所以我非常清楚这一点。然而,不同之处在于 isinst 之后 之后的额外转换类。我承认,差别很小。
    • 我认为 JIT 编译器应该能够优化该类转换。但我不知道目前是否有。
    • 顺便说一句,如果 object 为 null,则不会引发异常。该表达式将评估为 false:stackoverflow.com/questions/7640043/…
    • @Rune 我一定是记错了……抱歉
    【解决方案2】:
    1. IList 提供了 IEnumerable 没有的某些方法。最重要的是,能够添加到它(有关更多信息,请查看msdn
    2. is 比较类型,返回是否可以将某个对象强制转换为类型。 as 实际上执行该转换,如果失败则返回 null。强制转换意味着将 A 类型的对象转换为 B 类型的对象,无论出于何种原因。

    【讨论】:

    • 大多数时候,在 C# 中,强制转换不会在类型之间转换对象。通常,它只是在运行时检查对象是否属于给定的编译时类型,如果是,则允许您将对象分配给所述类型的变量。 (如果不是,则返回null 或抛出异常,具体取决于您使用parens 还是as。)
    • 确实,它更常指的是强制,而不是转换
    猜你喜欢
    • 2011-03-06
    • 1970-01-01
    • 2020-02-10
    • 2019-02-14
    • 1970-01-01
    • 2010-11-12
    • 1970-01-01
    • 2014-12-07
    相关资源
    最近更新 更多