编译器无法选择接口和异常之间的重载

时间:2008-10-07 14:34:54

标签: c# .net compiler-construction

尝试使用可以为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继承的

5 个答案:

答案 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构造函数而不是工厂方法来防止这种混淆