Jay said:
Göran,
Read the statement again, I was referring to C#:
If you don't override "==" in C# it is used for identity (it reverts to
the IL equevilent of Object.ReferenceEquals); if you do override "="
then it would (hopefully) be used for equality.
public class Class1
{
}
Class1 c1 = new Class1(), c2 = c1;
Debug.WriteLine(c1 == c2);
Of course it does. If you don't override the operator, it's inherited,
and that is the way that you compare two objects.
If you don't like it that way, you can always do it exactly the same way
VB does:
Debug.WriteLine(Microsoft.VisualBasic.CompilerServices.Operators.CompareObjectEqual(c1,c2));
The method is implemented as:
======
Public Shared Function CompareObjectEqual(ByVal Left As Object, ByVal
Right As Object, ByVal TextCompare As Boolean) As Object
Dim class1 As CompareClass = Operators.CompareObject2(Left,
Right, TextCompare)
Select Case class1
Case CompareClass.Unordered
Return False
Case CompareClass.UserDefined
Return
Operators.InvokeUserDefinedOperator(UserDefinedOperator.Equal, New
Object() { Left, Right })
Case CompareClass.Undefined
Throw
Operators.GetNoValidOperatorException(UserDefinedOperator.Equal, Left,
Right)
End Select
Return (class1 = CompareClass.Equal)
End Function
======
The real work is done in the CompareObject2 method, which is implemented as:
======
Private Shared Function CompareObject2(ByVal Left As Object, ByVal Right
As Object, ByVal TextCompare As Boolean) As CompareClass
Dim code1 As TypeCode
Dim code2 As TypeCode
Dim convertible1 As IConvertible = TryCast(Left,IConvertible)
If (convertible1 Is Nothing) Then
If (Left Is Nothing) Then
code1 = TypeCode.Empty
Else
code1 = TypeCode.Object
End If
Else
code1 = convertible1.GetTypeCode
End If
Dim convertible2 As IConvertible = TryCast(Right,IConvertible)
If (convertible2 Is Nothing) Then
If (Right Is Nothing) Then
code2 = TypeCode.Empty
Else
code2 = TypeCode.Object
End If
Else
code2 = convertible2.GetTypeCode
End If
If (code1 = TypeCode.Object) Then
Dim chArray1 As Char() = TryCast(Left,Char())
If ((Not chArray1 Is Nothing) AndAlso (((code2 =
TypeCode.String) OrElse (code2 = TypeCode.Empty)) OrElse ((code2 =
TypeCode.Object) AndAlso TypeOf Right Is Char()))) Then
Left = New String(chArray1)
convertible1 = DirectCast(Left, IConvertible)
code1 = TypeCode.String
End If
End If
If (code2 = TypeCode.Object) Then
Dim chArray2 As Char() = TryCast(Right,Char())
If ((Not chArray2 Is Nothing) AndAlso ((code1 =
TypeCode.String) OrElse (code1 = TypeCode.Empty))) Then
Right = New String(chArray2)
convertible2 = DirectCast(Right, IConvertible)
code2 = TypeCode.String
End If
End If
Select Case ((code1 * (TypeCode.String Or TypeCode.Object)) + code2)
Case TypeCode.Empty
Return CompareClass.Equal
Case TypeCode.Boolean
Return Operators.CompareBoolean(False,
convertible2.ToBoolean(Nothing))
Case TypeCode.Char
Return Operators.CompareChar(ChrW(0),
convertible2.ToChar(Nothing))
Case TypeCode.SByte
Return Operators.CompareInt32(0,
convertible2.ToSByte(Nothing))
Case TypeCode.Byte
Return Operators.CompareInt32(0,
convertible2.ToByte(Nothing))
Case TypeCode.Int16
Return Operators.CompareInt32(0,
convertible2.ToInt16(Nothing))
Case TypeCode.UInt16
Return Operators.CompareInt32(0,
convertible2.ToUInt16(Nothing))
Case TypeCode.Int32
Return Operators.CompareInt32(0,
convertible2.ToInt32(Nothing))
Case TypeCode.UInt32
Return Operators.CompareUInt32(0,
convertible2.ToUInt32(Nothing))
Case TypeCode.Int64
Return Operators.CompareInt64(CLng(0),
convertible2.ToInt64(Nothing))
Case TypeCode.UInt64
Return Operators.CompareUInt64(0,
convertible2.ToUInt64(Nothing))
Case TypeCode.Single
Return Operators.CompareSingle(0!,
convertible2.ToSingle(Nothing))
Case TypeCode.Double
Return Operators.CompareDouble(0,
convertible2.ToDouble(Nothing))
Case TypeCode.Decimal
Return
Operators.CompareDecimal(DirectCast(Decimal.Zero, IConvertible),
convertible2)
Case TypeCode.DateTime
Return Operators.CompareDate(DateTime.MinValue,
convertible2.ToDateTime(Nothing))
Case TypeCode.String
Return DirectCast(Operators.CompareString(Nothing,
convertible2.ToString(Nothing), TextCompare), CompareClass)
Case DirectCast(57, TypeCode)
Return
Operators.CompareBoolean(convertible1.ToBoolean(Nothing), False)
Case DirectCast(60, TypeCode)
Return
Operators.CompareBoolean(convertible1.ToBoolean(Nothing),
convertible2.ToBoolean(Nothing))
Case DirectCast(62, TypeCode)
Return
Operators.CompareInt32(Operators.ToVBBool(convertible1),
convertible2.ToSByte(Nothing))
Case DirectCast(63, TypeCode), DirectCast(64, TypeCode)
Return
Operators.CompareInt32(Operators.ToVBBool(convertible1),
convertible2.ToInt16(Nothing))
Case DirectCast(65, TypeCode), DirectCast(66, TypeCode)
Return
Operators.CompareInt32(Operators.ToVBBool(convertible1),
convertible2.ToInt32(Nothing))
Case DirectCast(67, TypeCode), DirectCast(68, TypeCode)
Return
Operators.CompareInt64(CLng(Operators.ToVBBool(convertible1)),
convertible2.ToInt64(Nothing))
Case DirectCast(69, TypeCode), DirectCast(72, TypeCode)
Return
Operators.CompareDecimal(Operators.ToVBBoolConv(convertible1), convertible2)
Case DirectCast(70, TypeCode)
Return
Operators.CompareSingle(CSng(Operators.ToVBBool(convertible1)),
convertible2.ToSingle(Nothing))
Case DirectCast(71, TypeCode)
Return
Operators.CompareDouble(CDbl(Operators.ToVBBool(convertible1)),
convertible2.ToDouble(Nothing))
Case DirectCast(75, TypeCode)
Return
Operators.CompareBoolean(convertible1.ToBoolean(Nothing),
Conversions.ToBoolean(convertible2.ToString(Nothing)))
Case DirectCast(76, TypeCode)
Return
Operators.CompareChar(convertible1.ToChar(Nothing), ChrW(0))
Case DirectCast(80, TypeCode)
Return
Operators.CompareChar(convertible1.ToChar(Nothing),
convertible2.ToChar(Nothing))
Case DirectCast(94, TypeCode), DirectCast(346, TypeCode),
DirectCast(360, TypeCode)
Return
DirectCast(Operators.CompareString(convertible1.ToString(Nothing),
convertible2.ToString(Nothing), TextCompare), CompareClass)
Case DirectCast(95, TypeCode)
Return
Operators.CompareInt32(convertible1.ToSByte(Nothing), 0)
Case DirectCast(98, TypeCode)
Return
Operators.CompareInt32(convertible1.ToSByte(Nothing),
Operators.ToVBBool(convertible2))
Case DirectCast(100, TypeCode)
Return
Operators.CompareInt32(convertible1.ToSByte(Nothing),
convertible2.ToSByte(Nothing))
Case DirectCast(101, TypeCode), DirectCast(102, TypeCode),
DirectCast(119, TypeCode), DirectCast(121, TypeCode), DirectCast(138,
TypeCode), DirectCast(139, TypeCode), DirectCast(140, TypeCode)
Return
Operators.CompareInt32(convertible1.ToInt16(Nothing),
convertible2.ToInt16(Nothing))
Case DirectCast(103, TypeCode), DirectCast(104, TypeCode),
DirectCast(123, TypeCode), DirectCast(141, TypeCode), DirectCast(142,
TypeCode), DirectCast(157, TypeCode), DirectCast(159, TypeCode),
DirectCast(161, TypeCode), DirectCast(176, TypeCode), DirectCast(177,
TypeCode), DirectCast(178, TypeCode), DirectCast(179, TypeCode),
DirectCast(180, TypeCode)
Return
Operators.CompareInt32(convertible1.ToInt32(Nothing),
convertible2.ToInt32(Nothing))
Case DirectCast(105, TypeCode), DirectCast(106, TypeCode),
DirectCast(125, TypeCode), DirectCast(143, TypeCode), DirectCast(144,
TypeCode), DirectCast(163, TypeCode), DirectCast(181, TypeCode),
DirectCast(182, TypeCode), DirectCast(195, TypeCode), DirectCast(197,
TypeCode), DirectCast(199, TypeCode), DirectCast(201, TypeCode),
DirectCast(214, TypeCode), DirectCast(215, TypeCode), DirectCast(216,
TypeCode), DirectCast(217, TypeCode), DirectCast(218, TypeCode),
DirectCast(219, TypeCode), DirectCast(220, TypeCode)
Return
Operators.CompareInt64(convertible1.ToInt64(Nothing),
convertible2.ToInt64(Nothing))
Case DirectCast(107, TypeCode), DirectCast(110, TypeCode),
DirectCast(129, TypeCode), DirectCast(145, TypeCode), DirectCast(148,
TypeCode), DirectCast(167, TypeCode), DirectCast(183, TypeCode),
DirectCast(186, TypeCode), DirectCast(205, TypeCode), DirectCast(221,
TypeCode), DirectCast(224, TypeCode), DirectCast(233, TypeCode),
DirectCast(235, TypeCode), DirectCast(237, TypeCode), DirectCast(239,
TypeCode), DirectCast(243, TypeCode), DirectCast(290, TypeCode),
DirectCast(291, TypeCode), DirectCast(292, TypeCode), DirectCast(293,
TypeCode), DirectCast(294, TypeCode), DirectCast(295, TypeCode),
DirectCast(296, TypeCode), DirectCast(297, TypeCode), DirectCast(300,
TypeCode)
Return Operators.CompareDecimal(convertible1,
convertible2)
Case DirectCast(108, TypeCode), DirectCast(127, TypeCode),
DirectCast(146, TypeCode), DirectCast(165, TypeCode), DirectCast(184,
TypeCode), DirectCast(203, TypeCode), DirectCast(222, TypeCode),
DirectCast(241, TypeCode), DirectCast(252, TypeCode), DirectCast(253,
TypeCode), DirectCast(254, TypeCode), DirectCast(255, TypeCode),
DirectCast(256, TypeCode), DirectCast(257, TypeCode), DirectCast(258,
TypeCode), DirectCast(259, TypeCode), DirectCast(260, TypeCode),
DirectCast(262, TypeCode), DirectCast(298, TypeCode)
Return
Operators.CompareSingle(convertible1.ToSingle(Nothing),
convertible2.ToSingle(Nothing))
Case DirectCast(109, TypeCode), DirectCast(128, TypeCode),
DirectCast(147, TypeCode), DirectCast(166, TypeCode), DirectCast(185,
TypeCode), DirectCast(204, TypeCode), DirectCast(223, TypeCode),
DirectCast(242, TypeCode), DirectCast(261, TypeCode), DirectCast(271,
TypeCode), DirectCast(272, TypeCode), DirectCast(273, TypeCode),
DirectCast(274, TypeCode), DirectCast(275, TypeCode), DirectCast(276,
TypeCode), DirectCast(277, TypeCode), DirectCast(278, TypeCode),
DirectCast(279, TypeCode), DirectCast(280, TypeCode), DirectCast(281,
TypeCode), DirectCast(299, TypeCode)
Return
Operators.CompareDouble(convertible1.ToDouble(Nothing),
convertible2.ToDouble(Nothing))
Case DirectCast(113, TypeCode), DirectCast(132, TypeCode),
DirectCast(151, TypeCode), DirectCast(170, TypeCode), DirectCast(189,
TypeCode), DirectCast(208, TypeCode), DirectCast(227, TypeCode),
DirectCast(246, TypeCode), DirectCast(265, TypeCode), DirectCast(284,
TypeCode), DirectCast(303, TypeCode)
Return
Operators.CompareDouble(convertible1.ToDouble(Nothing),
Conversions.ToDouble(convertible2.ToString(Nothing)))
Case DirectCast(114, TypeCode)
Return
Operators.CompareInt32(convertible1.ToByte(Nothing), 0)
Case DirectCast(117, TypeCode)
Return
Operators.CompareInt32(convertible1.ToInt16(Nothing),
Operators.ToVBBool(convertible2))
Case DirectCast(120, TypeCode)
Return
Operators.CompareInt32(convertible1.ToByte(Nothing),
convertible2.ToByte(Nothing))
Case DirectCast(122, TypeCode), DirectCast(158, TypeCode),
DirectCast(160, TypeCode)
Return
Operators.CompareInt32(convertible1.ToUInt16(Nothing),
convertible2.ToUInt16(Nothing))
Case DirectCast(124, TypeCode), DirectCast(162, TypeCode),
DirectCast(196, TypeCode), DirectCast(198, TypeCode), DirectCast(200,
TypeCode)
Return
Operators.CompareUInt32(convertible1.ToUInt32(Nothing),
convertible2.ToUInt32(Nothing))
Case DirectCast(126, TypeCode), DirectCast(164, TypeCode),
DirectCast(202, TypeCode), DirectCast(234, TypeCode), DirectCast(236,
TypeCode), DirectCast(238, TypeCode), DirectCast(240, TypeCode)
Return
Operators.CompareUInt64(convertible1.ToUInt64(Nothing),
convertible2.ToUInt64(Nothing))
Case DirectCast(133, TypeCode)
Return
Operators.CompareInt32(convertible1.ToInt16(Nothing), 0)
Case DirectCast(136, TypeCode)
Return
Operators.CompareInt32(convertible1.ToInt16(Nothing),
Operators.ToVBBool(convertible2))
Case DirectCast(152, TypeCode)
Return
Operators.CompareInt32(convertible1.ToUInt16(Nothing), 0)
Case DirectCast(155, TypeCode)
Return
Operators.CompareInt32(convertible1.ToInt32(Nothing),
Operators.ToVBBool(convertible2))
Case DirectCast(171, TypeCode)
Return
Operators.CompareInt32(convertible1.ToInt32(Nothing), 0)
Case DirectCast(174, TypeCode)
Return
Operators.CompareInt32(convertible1.ToInt32(Nothing),
Operators.ToVBBool(convertible2))
Case DirectCast(190, TypeCode)
Return
Operators.CompareUInt32(convertible1.ToUInt32(Nothing), 0)
Case DirectCast(193, TypeCode)
Return
Operators.CompareInt64(convertible1.ToInt64(Nothing),
CLng(Operators.ToVBBool(convertible2)))
Case DirectCast(209, TypeCode)
Return
Operators.CompareInt64(convertible1.ToInt64(Nothing), CLng(0))
Case DirectCast(212, TypeCode)
Return
Operators.CompareInt64(convertible1.ToInt64(Nothing),
CLng(Operators.ToVBBool(convertible2)))
Case DirectCast(228, TypeCode)
Return
Operators.CompareUInt64(convertible1.ToUInt64(Nothing), 0)
Case DirectCast(231, TypeCode)
Return Operators.CompareDecimal(convertible1,
Operators.ToVBBoolConv(convertible2))
Case DirectCast(247, TypeCode)
Return
Operators.CompareSingle(convertible1.ToSingle(Nothing), 0!)
Case DirectCast(250, TypeCode)
Return
Operators.CompareSingle(convertible1.ToSingle(Nothing),
CSng(Operators.ToVBBool(convertible2)))
Case DirectCast(266, TypeCode)
Return
Operators.CompareDouble(convertible1.ToDouble(Nothing), 0)
Case DirectCast(269, TypeCode)
Return
Operators.CompareDouble(convertible1.ToDouble(Nothing),
CDbl(Operators.ToVBBool(convertible2)))
Case DirectCast(285, TypeCode)
Return Operators.CompareDecimal(convertible1,
DirectCast(Decimal.Zero, IConvertible))
Case DirectCast(288, TypeCode)
Return Operators.CompareDecimal(convertible1,
Operators.ToVBBoolConv(convertible2))
Case DirectCast(304, TypeCode)
Return
Operators.CompareDate(convertible1.ToDateTime(Nothing), DateTime.MinValue)
Case DirectCast(320, TypeCode)
Return
Operators.CompareDate(convertible1.ToDateTime(Nothing),
convertible2.ToDateTime(Nothing))
Case DirectCast(322, TypeCode)
Return
Operators.CompareDate(convertible1.ToDateTime(Nothing),
Conversions.ToDate(convertible2.ToString(Nothing)))
Case DirectCast(342, TypeCode)
Return
DirectCast(Operators.CompareString(convertible1.ToString(Nothing),
Nothing, TextCompare), CompareClass)
Case DirectCast(345, TypeCode)
Return
Operators.CompareBoolean(Conversions.ToBoolean(convertible1.ToString(Nothing)),
convertible2.ToBoolean(Nothing))
Case DirectCast(347, TypeCode), DirectCast(348, TypeCode),
DirectCast(349, TypeCode), DirectCast(350, TypeCode), DirectCast(351,
TypeCode), DirectCast(352, TypeCode), DirectCast(353, TypeCode),
DirectCast(354, TypeCode), DirectCast(355, TypeCode), DirectCast(356,
TypeCode), DirectCast(357, TypeCode)
Return
Operators.CompareDouble(Conversions.ToDouble(convertible1.ToString(Nothing)),
convertible2.ToDouble(Nothing))
Case DirectCast(358, TypeCode)
Return
Operators.CompareDate(Conversions.ToDate(convertible1.ToString(Nothing)),
convertible2.ToDateTime(Nothing))
End Select
If ((code1 <> TypeCode.Object) AndAlso (code2 <>
TypeCode.Object)) Then
Return CompareClass.Undefined
End If
Return CompareClass.UserDefined
End Function
======
Yeah, that is much better.