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

Eri*_*Law 1 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()'.)

结果

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

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

Ser*_*rvy 5

  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();
    }
}
Run Code Online (Sandbox Code Playgroud)