1

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() 方法。这些新的特定于类型的枚举器由针对新版本编译的代码调用,而尚未重新编译的旧插件仍然从基类中检索非泛型枚举器。*

4

1 回答 1

5
  1. 您需要提供一些GetEnumerator 方法来返回实际的 HTTPHeaderItem 类型,以便避免进行强制转换。这意味着要么实现IEnumerable<HTTPHeaderItem>或让一个隐式GetEnumerator方法返回实际类型。在一般情况下,这意味着您可以依赖 Duck 输入,而不是 implement 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();
    }
}
于 2013-01-31T20:24:04.180 回答