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

本文关键字:情况下 IEnumerable 兼容性 二进制 是否 | 更新日期: 2023-09-27 17:57:06

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. 是否可以在不隐藏(通过显式接口实现)旧 GetEnumerator() 方法的情况下实现IEnumerable<HTTPHeaderItem>?隐藏旧方法会破坏与旧扩展的二进制兼容性(例如 Method not found: 'System.Collections.IEnumerator Fiddler.HTTPHeaders.GetEnumerator()'.)

结果

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

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

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

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

  2. 确定。 只需隐藏IEnumerable<HTTPHeaderItem>实现而不是IEnumerable实现即可。 这正是数组所做的(以保持二进制兼容性)。

下面是一个简单的示例:

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