接口继承:方法不显示!
我有一个接口继承问题,已经困扰我一段时间了。这似乎没有任何意义,我只能得出结论,我错过了一些基本的东西。
概述
下面的代码来自我们的 ORM 工具的流畅界面的一部分。它提供了类似 SQL 的语法来从数据库中提取数据。您不必完全理解所有相互关系才能理解问题——真正的问题是 EndClause 方法。
EndClause 问题
有一种名为 EndClause 的方法没有出现在预期的位置 - IOrderQueryRoot。据我所知,它应该出现,因为它继承自两个不同的接口,都有一个名为 EndClause 的方法,但是当我使用一个实现 IOrderQueryRoot 的对象时,EndClause不会在智能感知中弹出。
下面还有一些更多的实现细节。
首先,如果您查看 IOrderQueryRoot(其中包含 EndClause),您可以看到它继承了 IHasOrderLogicalOperators 和 IHasOrderFields(也包含 EndClause)。
Public Interface IHasOrderLogicalOperators
Function [And]() As IHasOrderFields
Function [AndNot]() As IHasOrderFields
Function [Not]() As IHasOrderFields
Function [Or]() As IHasOrderFields
Function [OrNot]() As IHasOrderFields
Function EndClause() As IHasOrderLogicalOperators
End Interface
Public Interface IHasOrderFields
Function OrderID(ByVal value As Int32) as IHasOrderLogicalOperators
Function OrderID() As IHasOrderComparisonOperators
Function PracticeID(ByVal value As Int32) as IHasOrderLogicalOperators
Function PracticeID() As IHasOrderComparisonOperators
'note: I cut about a page of additional order-related fields you don't need to see.
Function BeginClause() As IHasOrderFields
Function EndClause() As IHasOrderLogicalOperators
End Interface
Public Interface IOrderQueryRoot
Inherits IHasOrderFields, IHasOrderLogicalOperators
End Interface
我认为这个问题一定与 EndClause 方法从继承链中的不同位置进入 IOrderQueryRoot 两次有关。它确实需要这样工作。
因为你可能想看看我实际使用接口的地方,所以这是我正在使用的代码:
Public Function EndClause() As IHasOrderLogicalOperators Implements IHasOrderFields.EndClause, IHasOrderLogicalOperators.EndClause
Me.Query.EndClause()
Return New OrderQueryElement(Query)
End Function
此时,接口工作正常——如果我要删除这个方法,VS 会尖叫我必须实现两个 EndClause 方法。当“最终开发人员”尝试针对接口实际编写代码时,问题就低了一层。
如果您有什么问题,请告诉我——这个问题已经让我发疯很长一段时间了!
I've got an interface inheritance issue that has been vexing me for some time. It doesn't seem to make any sense, and I can only conclude that I'm missing something fundamental.
Overview
The code below is from part of a fluent interface for our ORM tool. It provides a SQL-like syntax for pulling data from the database. You don't have to completely grok all the interrelations to understand the problem -- the real issue is the EndClause method.
The EndClause Issue
There's a method called EndClause that doesn't show up in one expected spot -- IOrderQueryRoot. As far as I know, it should show up because it inherits from two different interfaces that both have a method called EndClause, but when I consume an object that implements IOrderQueryRoot, EndClause does not pop up in intellisense.
There are some more implementation details below.
First though, if you look at IOrderQueryRoot (which contains EndClause), you can see that it inherits IHasOrderLogicalOperators, and also IHasOrderFields (which also contains EndClause).
Public Interface IHasOrderLogicalOperators
Function [And]() As IHasOrderFields
Function [AndNot]() As IHasOrderFields
Function [Not]() As IHasOrderFields
Function [Or]() As IHasOrderFields
Function [OrNot]() As IHasOrderFields
Function EndClause() As IHasOrderLogicalOperators
End Interface
Public Interface IHasOrderFields
Function OrderID(ByVal value As Int32) as IHasOrderLogicalOperators
Function OrderID() As IHasOrderComparisonOperators
Function PracticeID(ByVal value As Int32) as IHasOrderLogicalOperators
Function PracticeID() As IHasOrderComparisonOperators
'note: I cut about a page of additional order-related fields you don't need to see.
Function BeginClause() As IHasOrderFields
Function EndClause() As IHasOrderLogicalOperators
End Interface
Public Interface IOrderQueryRoot
Inherits IHasOrderFields, IHasOrderLogicalOperators
End Interface
I think the problem must have something to do with the fact that the EndClause method comes into IOrderQueryRoot twice from different places in the inheritance chain. It does need to work that way.
Since you might want to see the place where I actually consume the interfaces, here's the code I'm using:
Public Function EndClause() As IHasOrderLogicalOperators Implements IHasOrderFields.EndClause, IHasOrderLogicalOperators.EndClause
Me.Query.EndClause()
Return New OrderQueryElement(Query)
End Function
At this point, the interface is working fine -- if I were to remove this method, VS would scream that I have to implement both EndClause methods. The problem is one level down, when the "end developer" is trying to actually write code against the interface.
Please let me know if something jumps out at you -- this one has been driving me crazy for a long time!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Intellisense 中不存在这种情况的原因是,通过接口 IOrderQueryRoot 调用函数 EndClause 是非法的,并会导致编译器错误。原因是如果您应该调用
IHasOrderLogicalOperators.EndClause
或IHasOrderFields.EndClause
,则无法与以下代码区分开。Intellisense 致力于仅建议合法代码。该代码不合法,因此未列出。
是的,在您的
IOrderQueryRoot
实现中,解析是明确的,因为只有一个函数。对于原始的 IOrderQueryRoot ,尽管此分辨率不明确,因此未正确列出。The reason why this doesn't exist in Intellisense is that calling the function EndClause via the interface
IOrderQueryRoot
is illegal and results in a compiler error. The reason why is it's not possible to distinguish from the following code if you should callIHasOrderLogicalOperators.EndClause
orIHasOrderFields.EndClause
.Intellisense strives to only suggest legal code. This code is not legal and hence it is not listed.
Yes, in your implementation of
IOrderQueryRoot
the resolution is unambiguous as there is a single function. For the rawIOrderQueryRoot
though this resolution is ambiguous and hence correctly not listed.