是否可以在不破坏二进制兼容性的情况下升级到通用 IEnumerable
本文关键字:情况下 IEnumerable 兼容性 二进制 是否 | 更新日期: 2023-09-27 17:57:06
Fiddler的HTTPHeaders类有一个成员Storage
,这是一个List<HTTPHeaderItem>
。
HTTPHeaders 类以 .NET 1.1 样式公开一个枚举器,因此:public System.Collections.IEnumerator GetEnumerator()
。此方法仅返回Storage.GetEnumerator()
。
问题:
-
不实施
IEnumerable<HTTPHeaderItem>
是否会降低性能?还是foreach(HTTPHeaderItem in oHTTPHeaders)
的编译足够聪明,可以识别它返回的对象也实现了 IEnumerable 的类型特定版本并避免了一堆强制转换? -
是否可以在不隐藏(通过显式接口实现)旧 GetEnumerator() 方法的情况下实现
IEnumerable<HTTPHeaderItem>
?隐藏旧方法会破坏与旧扩展的二进制兼容性(例如Method not found: 'System.Collections.IEnumerator Fiddler.HTTPHeaders.GetEnumerator()
'.)
结果
*正如 Servy 在下面的回答中所指出的,在添加返回类型专用枚举器的公共 GetEnumerable() 时,没有简单的方法可以避免破坏二进制兼容性。
但是,在我的特定场景中,我有点幸运。HTTPHeaders是一个基类,几乎所有调用者都使用两个派生类(HTTPRequestHeaders和HTTPResponseHeaders)之一。我已经将公共泛型 GetEnumerator() 方法添加到每个派生类中。这些新的特定于类型的枚举器由针对新版本编译的代码调用,而尚未重新编译的旧插件仍从基类中检索非泛型枚举器。
-
您需要提供一些 GetEnumerator 方法,该方法返回实际的 HTTPHeaderItem 类型,以便避免强制转换。 这意味着要么实现
IEnumerable<HTTPHeaderItem>
,要么让一个隐式GetEnumerator
方法返回实际类型。 在一般情况下,这意味着您可以依赖 Duck 类型,而不是实现IEnumerable<T>
,但在您的情况下,由于这种方法已经存在错误的签名,这是不可能的。 -
确定。 只需隐藏
IEnumerable<HTTPHeaderItem>
实现而不是IEnumerable
实现即可。 这正是数组所做的(以保持二进制兼容性)。
下面是一个简单的示例:
public class Foo : IEnumerable, IEnumerable<HTTPHeaderItem>
{
public IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
IEnumerator<HTTPHeaderItem> IEnumerable<HTTPHeaderItem>.GetEnumerator()
{
throw new NotImplementedException();
}
}