接口继承:方法不显示!

发布于 2024-08-21 19:43:54 字数 1997 浏览 6 评论 0原文

我有一个接口继承问题,已经困扰我一段时间了。这似乎没有任何意义,我只能得出结论,我错过了一些基本的东西。

概述

下面的代码来自我们的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧人 2024-08-28 19:43:54

Intellisense 中不存在这种情况的原因是,通过接口 IOrderQueryRoot 调用函数 EndClause 是非法的,并会导致编译器错误。原因是如果您应该调用 IHasOrderLogicalOperators.EndClauseIHasOrderFields.EndClause,则无法与以下代码区分开。

Dim v1 As IOrderQueryRoot
v1.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 call IHasOrderLogicalOperators.EndClause or IHasOrderFields.EndClause.

Dim v1 As IOrderQueryRoot
v1.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 raw IOrderQueryRoot though this resolution is ambiguous and hence correctly not listed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文