尝试使用可以为XML解析提供位置参考的excpetion类,发现了一个有趣的行为 - 当我尝试将XmlReader作为参数传递时,编译器无法在使用接口的重载和需要System.Exception的重载之间进行选择。
Detais正在关注:
//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继承的
答案 0 :(得分:1)
该行:
//fails
throw new FilterXmlParseException("<Filter> element expected", reader);
因为XmlReader没有实现IXmlLineInfo。我不确定你的演员阵容是否有效,但不会静态检查演员阵容。如果它确实有效,那是因为具体类(继承自XmlReader)实现了这个接口,但是编译器无法知道它。
答案 1 :(得分:0)
它无法为XmlReader调用选择重载,因为既不重载也是可接受的。 XmlReader不从Exception继承,因此第一次调用无效。 XmlReader也没有实现IXmlLineInfo。
它在第二种情况下起作用的原因是你强迫演员。但是,我相信如果您实际运行该代码,它将抛出InvalidCastException。阅读有关XmlReader的文档,您将看到它实现的唯一接口是IDispoable。
http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.aspx
答案 2 :(得分:0)
看起来它是实现IXmlLineInfo的XmlTextReader,而不是XmlReader
http://msdn.microsoft.com/en-us/library/system.xml.ixmllineinfo(VS.71).aspx
答案 3 :(得分:0)
你遗漏了关键部分:
XmlReader reader = XmlTextReader.Create(sreader, readerSettings);
您调用的方法会返回XmlTextReader
,但您的变量类型为XmlReader
。
转换在运行时发生,因此reader
的运行时值可以强制转换为IXmlLineInfo
,因为XmlTextReader
支持该接口,即使XmlReader
没有。
重载资源在编译时发生,因为XmlReader
不支持IXmlLineInfo
,它不能与签名匹配。
你可以写一下来解决它:
XmlTextReader reader = (XmlTextReader)XmlTextReader.Create(sreader, readerSettings);
请注意,您需要进行投射,因为Create
的返回类型为XmlReader
,即使它实际返回XmlTextReader
。
答案 4 :(得分:0)
感谢您的回答。
我知道基类没有实现IXmlLineInfo。
但实际上我正在使用XmlTextReader.Create来获取实际读者的实例。
所以我认为实际的解决方案是使用XmlTextReader构造函数而不是工厂方法来防止这种混淆