是否可以在不破坏二进制兼容性的情况下升级到Generic IEnumerable

时间:2013-01-31 20:15:39

标签: c# ienumerable

Fiddler的HTTPHeaders类有一个Storage成员,List<HTTPHeaderItem>

HTTPHeaders类公开了.NET 1.1样式的枚举器:public System.Collections.IEnumerator GetEnumerator()。此方法只返回Storage.GetEnumerator()

问题:

  1. 不实施IEnumerable<HTTPHeaderItem>是否会导致性能下降?或者foreach(HTTPHeaderItem in oHTTPHeaders)的编译是否足够聪明,以便识别它所获得的对象还实现了IEnumerable的特定于类型的版本并避免了一堆投射?

  2. 甚至可能实现IEnumerable<HTTPHeaderItem>而不隐藏(通过显式接口实现)旧的GetEnumerator()方法?隐藏旧方法会破坏与旧版扩展程序的二进制兼容性(例如Method not found: 'System.Collections.IEnumerator Fiddler.HTTPHeaders.GetEnumerator()'。)

  3. 结果

    *正如Servy在下面的回答所指出的,在添加返回类型专用的枚举器的公共GetEnumerable()时,没有简单的方法可以避免破坏二进制兼容性。

    但是,在我的具体情况下,我有点幸运。 HTTPHeaders是一个基类,几乎所有调用者都使用两个派生类之一(HTTPRequestHeaders和HTTPResponseHeaders)。我已经为每个派生类添加了公共通用GetEnumerator()方法。这些新的特定于类型的枚举器由针对新版本编译的代码调用,而尚未重新编译的旧插件仍然从基类中检索非泛型枚举器。*

1 个答案:

答案 0 :(得分:5)

  1. 您需要提供某些 GetEnumerator方法,该方法返回要避免的强制转换的实际HTTPHeaderItem类型。这意味着实现IEnumerable<HTTPHeaderItem>或使用一个隐式GetEnumerator方法返回实际类型。在一般情况下,这意味着你可以依赖Duck输入,而不是实现IEnumerable<T>,但在你的情况下,由于这种方法已经存在错误的签名,这是不可能的。

  2. 不确定。只需隐藏IEnumerable<HTTPHeaderItem>实施而不是IEnumerable实施。这正是数组所做的(维护二进制兼容性)。

  3. 这是一个简单的例子:

    public class Foo : IEnumerable, IEnumerable<HTTPHeaderItem>
    {
    
        public IEnumerator GetEnumerator()
        {
            throw new NotImplementedException();
        }
    
        IEnumerator<HTTPHeaderItem> IEnumerable<HTTPHeaderItem>.GetEnumerator()
        {
            throw new NotImplementedException();
        }
    }