如何在模块中覆盖Object.Equals()方法?

3
也许问题的标题不太恰当,因为模块中的方法不能被遮蔽,但实质上我想重新声明一个基类成员并隐藏它,同时又不失调用它并返回正确值的机会。
通常我这样做是针对类:
<EditorBrowsable(EditorBrowsableState.Never)>
Public Shadows Function Equals(ByVal obj As Object) As Boolean
    Return MyBase.Equals(obj)
End Function

这是关于结构的内容:

<EditorBrowsable(EditorBrowsableState.Never)>
Public Shadows Function Equals(ByVal obj As Object) As Boolean
    Return Object.Equals(obj, Me)
End Function

我尝试使用一个模块来复制这种行为时遇到的问题是,我应该使用什么来填充下面示例中的可疑参数,因为我不能使用Me、模块名称或构造函数,我明白了,但我需要使用什么呢?

Module TestModule

    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Function Equals(ByVal obj As Object) As Boolean
        Return Object.Equals(obj, ?)
    End Function

End Module

如果您调用标准的 Object.Equals,那么这有什么作用呢? - Ňɏssa Pøngjǣrdenlarp
@Plutonix 感谢您的评论。原因只是为了设计,我非常喜欢设计类,我想看到我的类的Intellisense自动完成框,而不包括在大多数情况下我永远不会使用的基本方法,例如Equals或ReferenceEquals,我将它们隐藏起来以进行设计,但我不想失去调用它们的效率能力。 - ElektroStudios
1
我不知道这是否有帮助,但VB模块的概念基本上是一个IDE强制执行的概念。如果你在一个不属于当前解决方案的类库(dll)中将<Microsoft.VisualBasic.CompilerServices.StandardModule>应用于一个类,你会看到它的Shared成员就像在VB模块中一样出现。 - TnTinMn
2个回答

2

这有规定...简单地说,你不能这样做。

只能在类级别上使用Shadows。这意味着Shadows元素的声明上下文必须是一个类,而不能是源文件、命名空间、接口、模块、结构或过程。

这就是为什么你可以在结构和类中使用...

请查看更多此处。底部显示了Shadows可以存在的上下文。

编辑 - 解决方案

不确定为什么您想要调用Object.Equals时可以使用标准的方法创建自己的函数来确定两个对象是否相等。

这里有一个简单的解决方案,你可以依据它工作,因为它已经被尝试并测试。此外,如果您想对许多对象使用Equals,那么您需要更多的结构来比较与之相比较的对象,这些结构将会覆盖Equals函数。

Module TestModule


    Sub Main()
        Dim a As New Person("Stack", "Overflow")
        Dim b As New Person("Stack", "Overflow")

        Console.WriteLine(a.Equals(b))

    End Sub

    Public Structure Person
        Private FirstName As String
        Private LastName As String

        Public Sub New(firstName As String, lastName As String)
            Me.FirstName = firstName
            Me.LastName = lastName
        End Sub

        <EditorBrowsable(EditorBrowsableState.Never)>
        Public Shadows Function Equals(ByVal obj As Object) As String
            Return If(Object.Equals(obj, Me), "TRUE", "FALSE").ToString
        End Function
    End Structure

End Module

现在你可能会想知道为什么Equals返回一个String,我特意这样做是为了让你看到它确实掩盖了基类,因为我返回了不同的类型,否则你就看不到。你可以将该函数更改为返回Boolean并更改返回值,它也能正常工作。


谢谢您的帮助,但是向模块添加一个结构(在我的情况下为空且没有用途的结构)不是我想要的。目前,我正在模拟模块级别的阴影,只需声明具有名称“Equals”的函数即可,但我有点迷失在理解我需要如何调用Object.Equals()内部的方式(第二个参数,应该是模块)。我将尝试检查在线的.NET Framework参考资料,以尝试发现Microsoft称为Object.Equals的第二个参数,以比较对象和模块。无论如何真的非常感谢! - ElektroStudios

0

这个在Object中定义的函数似乎是你试图模仿的那个:

Public Overridable Function Equals (obj As Object) As Boolean

然而,这在模块中不存在。您在模块名称后面看到Intellisense建议的“Equals”是共享的。

Public Shared Function Equals (objA As Object, objB As Object) As Boolean

您可以在文档中单独查看它们。要停止Intellisense建议它,只需在您的模块中包含此内容:

<EditorBrowsable(EditorBrowsableState.Never)> _
Public Function Equals(objA As Object, objB As Object) As Boolean
    Return Object.Equals(objA, objB)
End Function

虽然看起来不是很好的设计


我刚刚升级到Visual Studio 2015,似乎现在我的问题变得没有意义了,因为在这个新的IDE中,Equals和ReferenceEquals方法在模块中不再由Intellisense显示(也许他们注意到这些方法在模块中没有任何意义),所以我现在不必遮蔽任何东西来隐藏它们... - ElektroStudios
我无法回到VS2013去验证你关于共享函数的说法,我不太相信自己这段时间一直在尝试重新定义错误的方法,如果我没有正确地注意到方法签名的区别,那就是我自己的失误了,不管怎样... 我无法验证它,但可能是真的,所以我接受了你的答案。谢谢。 - ElektroStudios
@ElektroStudios,能否解释一下这是如何解决你的问题的,我很好奇。你接受的答案仍然缺乏关于为什么不能做到的细节,就像我所解释的那样... - Trevor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接