【问题标题】:I am having a CA1067 violation on IEquatable(Of T) and can't solve it我在 IEquatable(Of T) 上遇到 CA1067 违规,无法解决
【发布时间】:2023-01-26 05:12:36
【问题描述】:

我已经尝试了几个小时并进行了大量重新编码,但可以摆脱 CA1067 违规。
使用:
Visual Studio 2022、.Net v6.0.13、VB.NET

对于解决问题的任何帮助以及对我做错事的见解,我将不胜感激。

所以案例如下:
我有一个模板类SimNode(Of P,A),其中P代表父节点的数据类型,A代表节点三个属性的数据类型。

Public Class SimNode(Of P, A)
    Implements ISimNode(Of P, A)
    Implements IEquatable(Of SimNode(Of P, A))

    '[a bunch of properties and methods]

    Public Overridable Shadows Function Equals(other As SimNode(Of P, A)) As Boolean Implements IEquatable(Of SimNode(Of P, A)).Equals
        If Not Parent.Equals(other.Parent) Then Return False
        If Depth <> other.Depth Then Return False
        ....
        Return True
    End Function
End Class

然后我需要创建另一个名为 SimNode 的类,它继承自 SimNode(UShort,UShort) 并需要一个 IEquatable(Of SimNode),因为只有唯一的 SimNode 实例将被添加到模板“容器”-> Container(Of T as IEquatable(Of T)) 中。
容器这个词是通用的,它可以是例如列表、字典或哈希集。

这个新类与父类完全相同,但多了一个成员(列表)。

Private Class SimNode
    Inherits SimNode(Of UShort, UShort)
    Implements IEquatable(Of SimNode)

    '[a bunch of properties and methods]

    Private Shadows Function Equals(other As SimNode) As Boolean Implements IEquatable(Of SimNode).Equals
        Return MyBase.Equals(other)
    End Function
End Class

尽管有额外的列表,但我的平等标准仍然与父类中的相同。
这种方法会导致 CA1067 违规,我就是无法纠正。

我将非常感谢任何帮助!

我尝试遵循 Visual Studio 的建议,但都会导致错误。在子类 (SimNode) 中覆盖方法 Equals 的建议将产生明显的错误,因为它不能覆盖基类,因为它们具有不同的签名。

我也解决了这个https://stackoverflow.com/questions/2441346/cascading-iequatableof-t 没有成功。

【问题讨论】:

  • 您似乎没有在任何一个类中覆盖 Equals(Object),这就是 CA1067 的内容。 (我还要提到,非泛型类型派生自同名的泛型类型是很奇怪的;撤销相当普遍,例如对于IEnumerable。)
  • 谢谢你的回答!这可能很愚蠢,但您可能知道得更多。当我确切知道类型时,覆盖 Equals(object) 有什么意义?
  • 您可以重载它,例如 Public Overloads Function Equals(other As SimNode(Of P, A)) As Boolean Implements IEquatable(Of SimNode(Of P, A)).Equals ... ,但不能隐藏它。如果需要,您可以覆盖Function Equals(obj As Object) As Boolean
  • 但你可能应该这样做,在某些用例中是必需的
  • 我怀疑如果有人将 Equals(Object) 重载称为更具体的重载,你实际上不想给出不同的答案......

标签: vb.net generics inheritance iequatable


【解决方案1】:

在收到所有很好的反馈后,我得出了解决违规问题的答案。 该代码与我的编码方式有点不同,但似乎这是正确的做法。 关于答案的一些反馈将很高兴知道我是否正确地做到了这一点,以及这是否是你们想要告诉我的! ;)

Module Program
    Sub Main()
        Dim storage As New Container(Of Y)
    End Sub

    Private Class Container(Of T As IEquatable(Of T))

    End Class

    Private Class X(Of P, A)
        Implements IEquatable(Of X(Of P, A))

        Public ReadOnly Parent As P
        Public ReadOnly Attribute As A

        Public Sub New(parent As P, attribute As A)
            Me.Parent = parent : Me.Attribute = attribute
        End Sub

        Public Overridable Function IEquatable_Equals(other As X(Of P, A)) As Boolean Implements IEquatable(Of X(Of P, A)).Equals
            If Not Parent.Equals(other.Parent) Then Return False
            If Not Attribute.Equals(other.Attribute) Then Return False

            Return True
        End Function

        Public Overrides Function Equals(obj As Object) As Boolean
            Return DirectCast(Me, IEquatable(Of X(Of P, A))).Equals(TryCast(obj, X(Of P, A)))
        End Function

        Public Overrides Function GetHashCode() As Integer
            Return MyBase.GetHashCode()
        End Function
    End Class

    Private Class Y
        Inherits X(Of UShort, UShort)
        Implements IEquatable(Of Y)

        Public ReadOnly Lines As List(Of Integer)

        Public Sub New(parent As UShort, attribute As UShort)
            MyBase.New(parent, attribute)
        End Sub

        Public Overloads Function Equals(other As Y) As Boolean Implements IEquatable(Of Y).Equals
            Return MyBase.IEquatable_Equals(other)
        End Function

        Public Overrides Function Equals(obj As Object) As Boolean
            Return DirectCast(Me, IEquatable(Of Y)).Equals(TryCast(obj, Y))
        End Function

        Public Overrides Function GetHashCode() As Integer
            Return Parent + Attribute
        End Function
    End Class
End Module

【讨论】:

  • 我会考虑将 X_Equals 重命名为 IEquatable_Equals。这个约定明确了目的是什么(从IEquatable提供Equals的实现)。它也与 VB 的 VBA 继承版本中实现的命名方式一致,尽管这显然不一定特别引人注目(毕竟,在 VBA 继承 VB 中,通常使用损坏的匈牙利语变量名称版本)。
  • 是的。该示例是强调基类的名称,可能更容易理解示例。感谢您的反馈!
  • 如果将 GetHashCode 委托给基类,则还必须将 Equals 委托给基类。如果您想要Equals 的不同逻辑,则必须相应地提供您自己的GetHashCode。否则很多东西都会坏掉。
  • 伙计们,我非常感谢您的所有反馈!我倾向于所有这些答案。我将尝试在答案中进行更正。无论你发现什么,只要保持点! :D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-25
  • 2011-03-17
  • 2020-06-30
  • 2023-03-20
  • 2020-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多