1

尝试使用可以为 XML 解析提供位置参考的 excpetion 类,发现了一个有趣的行为 - 当我尝试将 XmlReader 作为参数传递时,编译器无法在使用接口的重载和需要 System.Exception 的重载之间进行选择。

详情如下:

//exception overloads:
public FilterXmlParseException(string message, Exception innerException)
        : base(message, innerException) { }
public FilterXmlParseException(string message, IXmlLineInfo lineInfo) {...}

//Usage:
XmlReader reader = ...
IXmlLineInfo lineinfo = (IXmlLineInfo)reader;

//fails
throw new FilterXmlParseException("<Filter> element expected", reader);

//ok
throw new FilterXmlParseException("<Filter> element expected", lineinfo);

它失败了,因为它无法选择正确的重载。但是为什么呢?我们看到 XmlReader 支持一个接口并且它不是从 System.Exception 继承的

4

5 回答 5

1

该行:

//fails
throw new FilterXmlParseException("<Filter> element expected", reader);

因为 XmlReader 没有实现 IXmlLineInfo。我不确定你的演员表是否有效,但演员表不是静态检查的。如果它真的有效,那是因为具体类(继承自 XmlReader)实现了这个接口,而编译器却无从得知。

于 2008-10-07T14:39:41.357 回答
0

它无法为 XmlReader 调用选择重载,因为这两种重载都不可接受。XmlReader 不继承自 Exception,所以第一次调用无效。XmlReader 也不实现 IXmlLineInfo。

它在第二种情况下起作用的原因是你在强迫演员。但是,我相信如果您要实际运行该代码,它会抛出 InvalidCastException。阅读有关 XmlReader 的文档,您会发现它实现的唯一接口是 IDispoable。

http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.aspx

于 2008-10-07T14:41:22.727 回答
0

看起来是实现 IXmlLineInfo 的 XmlTextReader,而不是 XmlReader

http://msdn.microsoft.com/en-us/library/system.xml.ixmllineinfo(VS.71).aspx

于 2008-10-07T14:42:43.677 回答
0

您遗漏了关键部分:

XmlReader reader = XmlTextReader.Create(sreader, readerSettings);

您调用一个返回 的方法XmlTextReader,但变量的类型是XmlReader

转换发生在运行时,因此reader可以将运行时值转换为IXmlLineInfo,因为XmlTextReader支持该接口,即使XmlReader不支持。

重载解决虽然发生在编译时,所以因为XmlReader不支持IXmlLineInfo,它不能与签名匹配。

您可以通过以下方式修复它:

XmlTextReader reader = (XmlTextReader)XmlTextReader.Create(sreader, readerSettings);

请注意,您需要强制转换,因为返回类型CreateXmlReader,即使它实际上返回 a XmlTextReader

于 2008-10-07T14:45:22.563 回答
0

感谢您的回答。

我知道基类没有实现 IXmlLineInfo。

但实际上我是在使用 XmlTextReader.Create 来获取实际阅读器的实例。

所以我想实际的解决方案是使用 XmlTextReader 构造函数而不是工厂方法来防止这种混淆

于 2008-10-07T14:50:11.523 回答