我在 IEquatable(Of T) 上遇到了 CA1067 违规,无法解决

I am having a CA1067 violation on IEquatable(Of T) and can't solve it

提问人:Paulo Borges 提问时间:1/26/2023 最后编辑:Paulo Borges 更新时间:1/26/2023 访问量:108

问:

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

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

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

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

然后,我需要创建另一个类,该类继承自并需要一个,因为只有唯一的实例才会添加到模板“容器”->中。
容器这个词是通用的,它可以是列表、字典或哈希集。
SimNodeSimNode(UShort,UShort)IEquatable(Of SimNode)SimNodeContainer(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的建议,但都会导致错误。在子类 () 中重写方法的建议会产生明显的错误,因为它无法重写基类,因为它们具有不同的签名。EqualsSimNode

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

vb.net 泛型 继承 可等

评论

1赞 Jon Skeet 1/26/2023
您似乎没有在任何一个类中被覆盖,这就是 CA1067 的意义所在。(我还想提一下,非泛型类型派生自同名的泛型类型是很奇怪的;反之亦然,例如。Equals(Object)IEnumerable
0赞 Paulo Borges 1/26/2023
感谢您的回答!这可能很傻,但你可能知道得更多。当我确切知道类型时,覆盖 Equals(object) 有什么意义?
0赞 Jimi 1/26/2023
您可以重载它,例如 ,但不能遮蔽它。如果需要,可以覆盖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
0赞 Jimi 1/26/2023
但你可能应该这样做,在某些用例中是必需的
0赞 Jon Skeet 1/26/2023
我怀疑如果有人将重载称为更具体的重载,您实际上并不想给出不同的答案......Equals(Object)

答:

0赞 Paulo Borges 1/26/2023 #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)
            Dim typ As Type : Dim datTyp As Integer
            Dim acceptingTypes As Integer() = {6, 8, 10, 12} '{Byte, USHort, UInteger, ULong}
            'check the type of P.
            typ = GetType(P) : datTyp = Type.GetTypeCode(typ)
            If Not acceptingTypes.Contains(datTyp) Then Throw New ArgumentException("Type 'P' is not acceptable.", NameOf(P))
            'check the type of A.
            typ = GetType(A) : datTyp = Type.GetTypeCode(typ)
            If Not acceptingTypes.Contains(datTyp) Then Throw New ArgumentException("Type 'A' is not acceptable.", NameOf(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 Parent.GetHashCode() + Attribute.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)
            Lines = New List(Of Integer)
        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 'Or Mybase.GetHashCode()?
        End Function
    End Class
End Module

评论

0赞 Craig 1/26/2023
我会考虑重命名为 .此约定明确了目的是什么(提供 from 的实现)。这也与VBA传统版本的VB中实现的命名方式一致,尽管这显然不一定特别引人注目(毕竟,在VBA传统VB中,使用匈牙利语变量名称的损坏版本是很常见的)。X_EqualsIEquatable_EqualsEqualsIEquatable
0赞 Paulo Borges 1/26/2023
是的。这个例子是强调基类的名称,也许更容易遵循这个例子。感谢您的反馈!
0赞 GSerg 1/26/2023
如果委托给基类,则还必须委托给基类。如果您想要不同的逻辑,则必须相应地提供自己的逻辑。否则很多东西都会坏掉。GetHashCodeEqualsEqualsGetHashCode
0赞 Paulo Borges 1/26/2023
伙计们,我非常感谢你们的所有反馈!我倾向于所有这些答案。我会尝试在答案中进行更正。只要记住你找到的任何东西!:D
0赞 Paulo Borges 1/26/2023
@GSerg 实际上,我不确定我是否得到了它。基类是 X,子类是 Y。我不认为我将 Y.GetHashCode() 委托给基类。 X.GetHashCode() 使用 Mybase.GetHashCode,因为我还不知道 P 和 A 将采用哪种类型。你能详细说明一下吗?