Runtime: Make System.HashCode available as standalone nuget package

Created on 18 Jan 2018  Â·  18Comments  Â·  Source: dotnet/runtime

The new System.HashCode type seems to be distributed as part of the core runtime (Based on this Comment by @morganbr in dotnet/runtime#19621).

The implementation is in System.Private.CoreLib.dll, so it would come as part of the runtime package. The contract is System.Runtime.dll.

System.HashCode could could benefit a wider audience, if it is distributed as standalone (.netstandard based) package. Every .NET developer on every platform sooner or later faces the problem to implement GetHashCode and doing so is fraught with pitfalls (there are more than 350 comments in total in this repro alone discussing a good hash code algorithm and a good API to expose it). Therefore an official standalone package with a good general purpose algorithm and a well designed API would be much appreciated. (I would even suggest to make System.HashCode part of .netstandard, but that's another topic).

api-suggestion area-System.Runtime

Most helpful comment

It seems that System.HashCode is now available in a standalone NuGet package:
https://www.nuget.org/packages/Microsoft.Bcl.HashCode

All 18 comments

Hi @MaStr11 - this is related to the existing tracking issue dotnet/runtime#24328. Please continue the discussion on dotnet/runtime#24328. Thanks! 😄

@joshfree

I'm sorry, but I must disagree. There are some fundamental differences between dotnet/runtime#24328 and this issue:

  1. dotnet/runtime#24328 discusses a future API, while I’m asking for a finished – soon to be released – API, to be made available by a different mechanism.
  2. dotnet/runtime#24328 seems to focus on hashing of streams. So, this is more about calculating checksums. System.HashCode only purpose is to serve making implementing GetHashCode easier, hence the return value of all System.HashCode methods is int. The API in dotnet/runtime#24328 is much more complicated and doesn’t really help implementing GetHashCode (e.g. public byte[] ComputeHash(ReadOnlySpan<byte> data);).
  3. The need for such an helper was raised in dotnet/roslyn#17646 by @Pilchie a few month ago and recently by @CyrusNajmabadi here

Original request:

We should test the framework and use them instead of hardcoding strange constants and stuff into the user's code if they invoke Generate Equals/GetHashCode.

Recent question from @CyrusNajmabadi about the availability System.HashCode

Note: what nuget package is this api even being included in for us to add a reference to?

In PR dotnet/Roslyn#24161 @CyrusNajmabadi already takes dependency on System.HashCode and it seemed he was as surprised as I was when he learned that System.HashCode wasn’t made available as package:

Ok. If that's the case, then it sounds like a user would get this if/when they move to a more recent Target Framework. That sort of thing is not at all a step i would have the "generate equals+hashcode" do to a user's project.

If there are any technical restrictions or other reasons that prevent System.HashCode from being released standalone, you can close this issue. But dotnet/runtime#24328 is not an approriate substitute for what I'm asking for. In other words: I want to be able to use System.HashCode in the full .Net Framework via Install-Package System.HashCode

This sounds like it would work similarly to ValueTuple (shipped as a combination of in-box and out-of-band). I do like the idea of making HashCode available to more people sooner, but I seem to recall that what we did with ValueTuple had some complications. @karelz, do you have details/thoughts on that?

shipped as a combination of in-box and out-of-band

We call these "partial OOBs" and they are incredibly hard and expensive to get right and maintain. We try really hard to avoid introducing new ones.

If we want to ship HashCode as independent package, the in-box and out-of-band packages should have different assembly names. It would be basically two different types. System.Diagnostics.Tracing (in-box) and Microsoft.Diagnostics.Tracing.EventSource (out of band) is a good prior art to use for this.

@CyrusNajmabadi, would Roslyn be able to take advantage of such an out-of-band package? You indicated previously that adding a package reference as part of a code fix might be too heavyweight.

would Roslyn be able to take advantage of such an out-of-band package?

Yes. In that we already have a mechnism to suggest nuget packages to users if they reference type names from those packages. We can also offer specific nuget packages in certain circumstances. For example, we know specifically about System.ValueTuple and we offer that package if you use tuples.

That said, IMO, there's little pressure to produce such a nuget package. I think we're at a reasonable point now. We have reasonably good stories for users who are targeting newer and older frameworks. If they're targetting newer frameworks, we'll use System.HashCode. If they're targetting older ones, we'll just spit out a reasonable GetHashCode impl.

IMO, this is a good-enough situation for users. It's already leaps and bounds ahead of what's the current state of affairs.

In other words: if someone did the work to make a nuget package, i think i'd b willing to surface that in some specialized way. But I'm not specifically asking for that package to be created. I'm satisfied with where we are now.

This sounds like it would work similarly to ValueTuple

I think this would be more like System.Numerics.Vectors or Microsoft.Net.Http, than ValueTuple, but yes that was the intend here. I was wondering why this package is part of the core runtime at all. Couldn't this be published completely out of band? What part of the core runtime takes dependency on this?

But I'm not specifically asking for that package to be created. I'm satisfied with where we are now.

While this is true from the IDE perspective, I'd like to point out that there are plenty developers out there, that would benefit from such a package. Take for instance all the the line-of-business application devs:

  • LOB developers are often forced to work on older platforms or the full framework (ASP.NET WebForms, WinForms, WPF, etc.)
  • LOB developers often need to implement equality, because they operate on business objects with composite keys (e.g. if you create an EF Code-First model).
  • LOB developers are much more relying on other libraries and don't do low level stuff that often. (xor is considered exotic in that domain)
  • LOB developers are not very vocal and therefore often ignored, but this is still a huge crowd (being one myself).

While those developers are well served by the generate equals/hashcode code fixes (as @CyrusNajmabadi pointed out), I still see great value in having System.HashCode on the other platforms because:

  • It is more performant
  • The generated code is less obscure (compare with and without System.HashCode)

I would also suggest to create a roslyn analyzer, that detects GetHashcode anti-patterns (e.g. a.GetHashCode() + b.GetHasCode()) and suggests to replace it with either System.HashCode or the code currently generated by the GetHashCode code generator. And in such a case a package import would make sense (while it doesn't make sense in the equals/gethashcode generator). I think this is something @CyrusNajmabadi had in mind when he said:

if someone did the work to make a nuget package, i think i'd b willing to surface that in some specialized way.

And as a last note. This package would nothing less than bring .NET on a par with Java 7 from 2011. [PS: You may have a look how reviewed JDK-6891113 back then 😄].

I can confirm the netfx LOB developers' hope that we'll finally get a palatable API for implementing GetHashCode.

That said, I don't want a repeat of the series of pitfalls that I recall coming with partial OOB packages. I think partial OOBs could do just fine if a lot of design effort was put into specifically making them a first-class scenario on all platforms, perhaps by creating an improved way to unify types at runtime.

While this is true from the IDE perspective, I'd like to point out that there are plenty developers out there, that would benefit from such a package. Take for instance all the the line-of-business application devs:

That's fine. My point is that this is something you guys need to figure out :) You get to decide if this is the right choice for how you deliver and whatnot. The IDE specifically is not requesting this. I'm only pointing this out so that whoever is making the decisions here doesn't think that that ask is coming from that direction.

Just checking in. I have multiple .NET Framework IEqualityComparer implementations duplicating corefx code with comments pointing to this issue. Is this a definite no, no hashing API will be available for .NET Framework developers?

It seems that System.Hashcode is going to be part of a future dotnet/standard#823

https://github.com/dotnet/standard/pull/823/files#diff-2e4f92c1322ad4c9bcd1107011e336a7R2439

This makes shipping it as a package irrelevant.

@MaStr11
.Net Framework will likely never implement .Net Standard 2.1
As such, can I suggest you reopen this issue?
Thanks

For anyone struggling with a need of System.HashCode and other polyfills from the future, take a look at this project: https://github.com/gapotchenko/Gapotchenko.FX/tree/master/Source/Gapotchenko.FX

It was created by contributors, colleagues and me to specifically address that kind of pains: https://github.com/gapotchenko/Gapotchenko.FX

Readily available as a NuGet package:
https://www.nuget.org/packages/Gapotchenko.FX

Enjoy and be productive.

It seems that System.HashCode is now available in a standalone NuGet package:
https://www.nuget.org/packages/Microsoft.Bcl.HashCode

Hi,
Sadly there are a bug in the s_seed initialization.
The value is always 0. And so we don't have the very useful property to obtain different hashcode at each process.
Could you please consider to fix this bug ?
Thanks

@fabricefou this issue is closed -- please open a new issue if you believe there's a bug or new work.

Yes you're right. #42808

Was this page helpful?
0 / 5 - 0 ratings

Related issues

GitAntoinee picture GitAntoinee  Â·  3Comments

bencz picture bencz  Â·  3Comments

sahithreddyk picture sahithreddyk  Â·  3Comments

EgorBo picture EgorBo  Â·  3Comments

noahfalk picture noahfalk  Â·  3Comments