我使用的是unity,而unity中没有元组,因此我创建了自己的元组类,因为我的Dictionary需要它。
Dictionary <Tuple<int,int>, Tile>
我创建的平铺课程,与解决此问题并不相关(至少我认为这无济于事)。
但是问题是我在元组中同时使用了负整数和正整数,并且当我将当前的GetHashCode()
与Tuples
一起使用时,有时会得到相同的HashCode,例如{当我返回哈希码时,{1}}和Tuple<-10, 8>
都给出-172。
是否有任何好的GetHashCode不会让我产生冲突?
老实说,我只使用运算符Tuple<-9,-10>
,因为我需要检查两个元组内部是否具有相同的整数,如果我能得到只有两个整数都冲突时才冲突的运算符==
相同和相同的顺序,它将解决我的问题。
其他一些小问题,我无法理解Equals覆盖,它确实可以正常工作,但是我不知道它的工作原理,因为我一直在更改每件事直到它起作用为止。
==
答案 0 :(得分:4)
GetHashCode()
不应无冲突。您应该使用它来确定两个事物可能是否是相同的对象,然后您必须进行彻底的检查以查看它们是否相同。
例如,您的==方法应这样写:
public static bool operator==(Tuple<T1, T2> obj1, Tuple<T1, T2> obj2)
{
if (ReferenceEquals(null, obj2))
return false;
if (obj1.GetHashCode() != obj2.GetHashCode())
{
return false;
}
return DefaultComparer<T1>.Equals(obj1.First, obj2.First) && DefaultComparer<T2>.Equals(obj1.Second, obj2.Second);
}
此外,不要忘记考虑obj1
和obj2
都是null
的情况。
如果您要实现自己的Tuple
,则可以考虑从Reference Source存储库中窃取Microsoft的存储,或者至少将其用作自己的基础。
答案 1 :(得分:3)
我使用的是unity,而unity中没有元组
如果您拥有 Unity 2017 及更高版本,它将支持Tuple。
转到编辑-> 项目设置->播放器-> 其他设置-> 配置-> 脚本运行时版本-> .NET 4.x等效。
重新加载或重新启动Visual Studio,您应该可以使用Tuple
。如果您不使用 Unity 2017 及更高版本,并且也不想更新,请参阅John的answer。
答案 2 :(得分:3)
这是reshaper会自动为您生成的内容。只需注意它们如何执行GetHashCode()和Equals。
docker run -v
答案 3 :(得分:-2)
我发现PropertyCompare
(*)在自动生成Equals
实现中很有用。它将自动比较所有公共属性(因此,如果您添加新的公共属性,则无需更改除外 GetHashCode
(甚至从技术上来说也是可选)。
它使用Cache
来达到合理的性能-一次性点击(每种类型)以生成用于比较的适当表达式。
using System;
using System.Linq.Expressions;
namespace YourApp
{
public class Tuple<T1, T2>
{
public T1 First { get; private set; }
public T2 Second { get; private set; }
public Tuple(T1 _First, T2 _Second)
{
First = _First;
Second = _Second;
}
public override int GetHashCode()
{
var hash = 0;
// Implement this however you like
hash = First.GetHashCode() * 17 + Second.GetHashCode() + First.GetHashCode();
return hash;
}
public static bool operator ==(Tuple<T1, T2> x, Tuple<T1, T2> y)
{
return PropertyCompare.Equal(x, y);
}
public static bool operator !=(Tuple<T1, T2> x, Tuple<T1, T2> y)
{
return !PropertyCompare.Equal(x, y);
}
public bool Equals(Tuple<T1, T2> other)
{
return PropertyCompare.Equal(this, other);
}
public override bool Equals(object obj)
{
return PropertyCompare.Equal(this, obj);
}
}
public static class Tuple
{
public static Tuple<T1, T2> New<T1, T2>(T1 first, T2 second)
{
var tuple = new Tuple<T1, T2>(first, second);
return tuple;
}
}
public class Program
{
public static void Main()
{
var bob1 = Tuple.New("a", 1);
var bob2 = Tuple.New("a", 1);
Console.WriteLine(bob1 == bob2);
Console.ReadLine();
}
}
public static class PropertyCompare
{
public static bool Equal<T>(T x, object y) where T : class
{
return Cache<T>.Compare(x, y as T);
}
public static bool Equal<T>(T x, T y)
{
if (x == null)
{
return y == null;
}
if (y == null)
{
return false;
}
return Cache<T>.Compare(x, y);
}
private static class Cache<T>
{
internal static readonly Func<T, T, bool> Compare;
static Cache()
{
var props = typeof(T).GetProperties();
if (props.Length == 0)
{
Compare = delegate { return true; };
return;
}
var x = Expression.Parameter(typeof(T), "x");
var y = Expression.Parameter(typeof(T), "y");
Expression body = null;
for (var i = 0; i < props.Length; i++)
{
var propEqual = Expression.Equal(
Expression.Property(x, props[i]),
Expression.Property(y, props[i]));
if (body == null)
{
body = propEqual;
}
else
{
body = Expression.AndAlso(body, propEqual);
}
}
Compare = Expression.Lambda<Func<T, T, bool>>(body, x, y)
.Compile();
}
}
}
}
(*)我在某个地方在线找到了它,可惜我不记得在哪里,而且Google在这里令我失望。