gpt4 book ai didi

c# - 当 ==、CompareTo() 和 Equals() 不一致时会发生什么?

转载 作者:行者123 更新时间:2023-11-30 15:31:34 26 4
gpt4 key购买 nike

几年前我写了一个程序来寻找字节的“好”二元运算符;字节 A左乘以字节 B产生字节 C .运算符定义为 256x256 字节矩阵。 A类实现的简化版本如下。

Equals()为真 IFF 数组中的所有 65536 个字节都相同。

CompareTo()将运算符的线性度与线性度更高(对加密货币不利)和线性度较低(对加密货币有利)的连续体进行比较。

所以有可能有两个实例,AB , 以下两项均为真:

A.Equals(B) = false
(A.ComparesTo(B) == 0) = true

我的问题比较少:这是个好主意吗?我知道答案是否定的,但考虑到测量线性度的大量计算成本和我的问题的狭窄性质,这个设计可行。代码也类似于:

if (localMinimumOperator < globalMinimumOperator)
{
localMinimumOperator = globalMinimumOperator;
}

对我来说更容易阅读。

我的问题是:这种分歧的后果是什么:==,CompareTo()== 0 , 和 Equals() ?或者:是否有描述哪个扩展使用哪个接口(interface)(IEquatableIComparable)的 LINQ 扩展方法列表?

比这篇关于 Enumerable 的 MSDN 文章更简洁的内容?

例如:

IEnumerable<BinaryOperation> distinct = orgList.Distinct();

电话 Equals(BinaryOperator)根据: Enumerable.Distinct<TSource> Method Contains()一样.我明白 Sort()OrderBy()使用调用 CompareTo() .

但是FindFirst()呢?和 BinarySearch()

我的示例类:

using System;
using System.Collections.Generic;
using System.Linq;


namespace Jww05
{
public class BinaryOperation : IEquatable<BinaryOperation>, IComparable<BinaryOperation>
{
#region ClassMembers

public List<List<byte>> TruthTable
{
get
{
// I don't like giving out the underlying list if I help it
var retVal = new List<List<byte>>(OperatorDefintion);
return retVal;
}
}

// private data store for TruthTable
private List<List<byte>> OperatorDefintion { get; set; }

public BinaryOperation()
{
// initial state is the Identity operator
OperatorDefintion = new List<List<byte>>();
for (int i = 0; i < 256; i++)
{
var curRow = new List<byte>();
for (int j = 0; j < 256; j++)
{
curRow.Add((byte)(i + j));
}
OperatorDefintion.Add(curRow);
}
}

private long MeasureOperatorLinearity()
{
var diagonalOffsets = new byte[] { 255, 0, 1 };

/*
* Code that measures linearity in the original code used the Fast Walsh Hadamard Transform.
* That should go here, but it is removed because the FWHT is clutter for the purposes of this question.
*
* Since I needed a stub for this, I decided to exacerbate the differnece
* between CompareTo() == 0 and Equals()
* by returning an arbitrary int in lieu of the long CPU intensive Fast Walsh Hadamard Transform.
*
* If the matrices are identical on an element-by-element basis, then the Faux Linearity will be the the same.
* If the faux linearity (sum of terms on the main diagonal and corners) are the same, the underlying matrices could be different on an element-by-element basis.
*/
long fauxLinearityMeasure = 0;
for (var currRow = 0; currRow < OperatorDefintion.Count(); ++currRow)
{
fauxLinearityMeasure *= 5;
fauxLinearityMeasure = diagonalOffsets.Select(diagonalOffset => (byte)(currRow + diagonalOffset))
.Aggregate(fauxLinearityMeasure, (current, offestedIndex) => current + (OperatorDefintion[offestedIndex][currRow]));
}

return (int)fauxLinearityMeasure;
}

#endregion ClassMembers

#region ComparisonOperations

public int CompareTo(BinaryOperation other)
{
long otherLinearity = other.MeasureOperatorLinearity();
long thisLinearity = MeasureOperatorLinearity();
long linearityDiff = thisLinearity - otherLinearity;

// case the differnece of the linarity measures into {-1, 0, 1}
return (0 < linearityDiff) ? 1
: (0 > linearityDiff) ? -1
: 0;
}

public static bool operator >(BinaryOperation lhs, BinaryOperation rhs)
{
if (ReferenceEquals(null, lhs) ||
ReferenceEquals(null, rhs))
{
return false;
}
return (0 < lhs.CompareTo(rhs));
}

public static bool operator <(BinaryOperation lhs, BinaryOperation rhs)
{
if (ReferenceEquals(null, lhs) ||
ReferenceEquals(null, rhs))
{
return false;
}
return (0 > lhs.CompareTo(rhs));
}

public static bool operator <=(BinaryOperation lhs, BinaryOperation rhs)
{
if (ReferenceEquals(null, lhs) ||
ReferenceEquals(null, rhs))
{
return false;
}

// equals is cheap
if (lhs.Equals(rhs))
{
return true;
}

return (0 > lhs.CompareTo(rhs));
}

public static bool operator >=(BinaryOperation lhs, BinaryOperation rhs)
{
if (ReferenceEquals(null, lhs) ||
ReferenceEquals(null, rhs))
{
return false;
}

// equals is cheap
if (lhs.Equals(rhs))
{
return true;
}

return (0 < lhs.CompareTo(rhs));
}

#endregion ComparisonOperations

#region EqualityOperators

public bool Equals(BinaryOperation other)
{
if (ReferenceEquals(null, other))
{
return false;
}

var otherTruthTable = other.TruthTable;
var thisTruthTable = TruthTable;
var isEquals = true;
for (int currRow = 0; currRow < thisTruthTable.Count(); ++currRow)
{
isEquals = isEquals && thisTruthTable[currRow].SequenceEqual(otherTruthTable[currRow]);
}

return isEquals;
}

public override bool Equals(object obj)
{
return Equals(obj as BinaryOperation);
}

public override int GetHashCode()
{
return OperatorDefintion.SelectMany(currRow => currRow)
.Aggregate(1, (current, currByte) => current * 5 + currByte);
}

public static bool operator ==(BinaryOperation lhs, BinaryOperation rhs)
{
if (ReferenceEquals(null, lhs) ||
ReferenceEquals(null, rhs))
{
return false;
}

return (0 == lhs.CompareTo(rhs));
}

public static bool operator !=(BinaryOperation lhs, BinaryOperation rhs)
{
if (ReferenceEquals(null, lhs) ||
ReferenceEquals(null, rhs))
{
return false;
}

return (0 != lhs.CompareTo(rhs));
}

#endregion EqualityOperators
}
}

最佳答案

What are the consequences of this divergence among: ==, CompareTo()== 0, and Equals()?

以后有人看你的代码会真的很讨厌你。

or alternately: Is there list of which linq extensions methods describing which extension use which interface (IEquitable or IComparable)?

我认为大部分内容是您自己找到的。一个好的经验法则是,通常没有什么界面被哪个 LINQ 函数使用令人惊讶(没有惊喜是良好设计的特征之一 - 不像你的)。例如:很明显,要对元素进行排序,有必要知道元素应该以何种特定顺序排列,单凭相等/不等式是不够的。 BinarySearch 还需要知道在搜索期间“走哪条路”——如果元素大于当前元素,它会重新定位到已排序数组的上部,如果更小,它会进入下部。同样:显然它需要 IComparable。对于 Distinct EqualsGetHashCode 就足够了 - 不需要排序来确定一组唯一元素。等等。

关于c# - 当 ==、CompareTo() 和 Equals() 不一致时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20479941/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com