-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
'Generate GetHashCode' generates a call to ValueType.GetHashCode #26141
Comments
So, stepping back, if you've ever used (a recent?) Roslyn to generate GetHashCode for a struct which uses non-default equality, you have a bug to go fix. The generated implementation breaks the invariant that if Equals returns true for two objects, their hash codes should be equal. You'll get false negatives for dictionary keys, or groups with duplicate keys, among other things. |
It looks like @CyrusNajmabadi has done something here which made it into master two months ago. Think the problem is already fixed in master? https://github.com/dotnet/roslyn/pull/24161/files#diff-a0d90f84d4625c53558ee000fb8ed2bbR147 |
@jnm2 this problem should already be fixed in the latest Visual Studio 15.7 Preview If you generate hashcode + equals on the following struct using System;
using System.Collections.Generic;
using System.Reflection;
struct Foo
{
public Type FixtureType { get; }
public MethodInfo Method { get; }
} you get this: using System;
using System.Collections.Generic;
using System.Reflection;
struct Foo
{
public Type FixtureType { get; }
public MethodInfo Method { get; }
public override bool Equals(object obj)
{
if (!(obj is Foo))
{
return false;
}
var foo = (Foo)obj;
return EqualityComparer<Type>.Default.Equals(FixtureType, foo.FixtureType) &&
EqualityComparer<MethodInfo>.Default.Equals(Method, foo.Method);
}
public override int GetHashCode()
{
var hashCode = 662238274;
hashCode = hashCode * -1521134295 + EqualityComparer<Type>.Default.GetHashCode(FixtureType);
hashCode = hashCode * -1521134295 + EqualityComparer<MethodInfo>.Default.GetHashCode(Method);
return hashCode;
}
} |
Closing as fixed in 15.7. |
This was fixed with #24161 |
VS 15.6.6.
If you use Roslyn's 'Generate GetHashCode...' suggestion on a struct, it asks you which properties to include, and then it generates code combining those with an additional hash,
base.GetHashCode()
:Just like when inheriting from
System.Object
, inheritors fromSystem.ValueType
are always going to want to replace the base has calculation not combine it. Not only can this easily result in incorrect hashes which contradict theEquals
implementation, many times the entire purpose of overridingValueType.GetHashCode
is to provide a better-performing implementation.The text was updated successfully, but these errors were encountered: