鉴于以下关键:
int key = Guid.NewGuid().GetHashCode();
Run Code Online (Sandbox Code Playgroud)
这个钥匙作为Guid的独特之处是独一无二的吗?
也许我是基础知识,但我还在学校学习这个C#的东西.据我所知,如果我将1加到最大值整数,哪一个是32位,结果将是负数.我读到C#提供了检查和未检查的关键字来处理溢出.已检查的关键字是一种东西,我发现它很有用,但未经检查的关键字怎么样?我真的找不到用于unchecked -keyworded块的有用的东西.有没有?接下来的两种方法如何相互不同?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Practice_6
{
class Program
{
static void Main(string[] args)
{
int value = Int32.MaxValue;
value++;
//Approach 1 to make a decision
if (value > Int32.MaxValue) {
//Do something
}
value = Int32.MaxValue;
//Approach 2 to make a decision
unchecked {
value++;
//Do something
}
//What's the difference between these two approaches to handle overflow?
}
}
Run Code Online (Sandbox Code Playgroud) 我有一个使用ConcurrentDictionary实现的缓存,我需要保留的数据取决于5个参数.所以从缓存中获取它的方法是:(为简单起见,这里只显示3个参数,我更改了数据类型以表示CarData的清晰度)
public CarData GetCarData(string carModel, string engineType, int year);
Run Code Online (Sandbox Code Playgroud)
我想知道在我的ConcurrentDictionary中使用哪种类型的密钥会更好,我可以这样做:
var carCache = new ConcurrentDictionary<string, CarData>();
// check for car key
bool exists = carCache.ContainsKey(string.Format("{0}_{1}_{2}", carModel, engineType, year);
Run Code Online (Sandbox Code Playgroud)
或者像这样:
var carCache = new ConcurrentDictionary<Tuple<string, string, int>, CarData>();
// check for car key
bool exists = carCache.ContainsKey(new Tuple(carModel, engineType, year));
Run Code Online (Sandbox Code Playgroud)
我不会将这些参数与其他任何地方一起使用,因此没有理由创建一个类来保持它们在一起.
我想知道哪种方法在性能和可维护性方面更好.
所以我试图弄清楚如何GetHashCode()在VB中正确覆盖大量的自定义对象.一些搜索引导我得到这个美妙的答案.
除了有一个问题:VB缺少.NET 4.0中的checked和unchecked关键字.据我所知,无论如何.因此,使用乔恩斯基特的实现,我想对具有三个主要成员一个相当简单的类创建这样一个覆盖:Name As String,Value As Int32,和[Type] As System.Type.因此,我提出:
Public Overrides Function GetHashCode() As Int32
Dim hash As Int32 = 17
hash = hash * 23 + _Name.GetHashCode()
hash = hash * 23 + _Value
hash = hash * 23 + _Type.GetHashCode()
Return hash
End Function
Run Code Online (Sandbox Code Playgroud)
问题:即使像这样的简单对象,Int32也太小了.我测试的特定实例将"Name"作为一个简单的5个字符的字符串,并且该哈希值足够接近Int32的上限,当它试图计算哈希值(Value)的第二个字段时,它会溢出.因为我找不到粒度checked/ unchecked支持的VB等价物,所以我无法解决这个问题.
我也不想删除整个项目中的Integer溢出检查.这个东西可能...... 40%完成(我做了,TBH),我有更多的代码要写,所以我需要这些溢出检查很长一段时间.
GetHashCode对于VB和Int32 ,Jon的版本的"安全"版本是什么?或者,.NET 4.0 在某个地方有checked/ unchecked我在MSDN上很难找到吗?
编辑:
根据链接的SO问题,最底层的一个不受欢迎的答案提供了一个 …
如果一个实现GetHashCode的方式-在那里它必须这样做-由乔恩斯基特概述这里.重复他的代码:
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
// Suitable nullity checks etc, of course :)
hash = hash * 23 + field1.GetHashCode();
hash = hash * 23 + field2.GetHashCode();
hash = hash * 23 + field3.GetHashCode();
return hash;
}
}
Run Code Online (Sandbox Code Playgroud)
用手滚动这个代码可以是容易出错,错误可能是微妙/很难发现(你交换+和*误?),它可能很难记住不同类型的组合规则,我不喜欢花费精神努力为不同的领域和课程一遍又一遍地写同样的东西.它还可以模糊重复噪声中最重要的细节之一(我记得包括所有字段吗?).
是否有使用.net库组合字段哈希码的简明方法?.显然我可以写自己的,但如果有一些惯用/内置的东西,我宁愿这样做.
举个例子,在Java中(使用JDK7),我可以使用以下方法实现:
@Override
public int hashCode()
{
return Objects.hash(field1, field2, field3);
}
Run Code Online (Sandbox Code Playgroud)
这确实有助于消除错误并专注于重要细节.
动机:我遇到了一个需要覆盖的C#类GetHashCode(),但它结合各种成分的哈希码的方式有一些严重的错误.用于组合哈希码的库函数对于避免这样的错误是有用的.
问题一般: 我有一个很大的2d点空间,人口稀少的点.可以把它想象成一个涂有黑点的大白色帆布.我必须迭代并搜索这些点很多.Canvas(点空间)可能很大,接近int的限制,并且在设置点之前它的大小是未知的.
这让我想到了哈希:
理想: 我需要一个带2D点的哈希函数,返回一个唯一的uint32.这样就不会发生碰撞.您可以假设uint32可以轻松计算Canvas上的点数.
重要提示:事先不可能知道画布的大小(甚至可能会改变),所以就像这样
canvaswidth*y + x
遗憾的是,这是不可能的.
我也试过很天真
abs(x)+ abs(y)
但这会产生太多的碰撞.
妥协: 一种散列函数,它提供非常低的碰撞概率.
任何人的想法?谢谢你的帮助.
此致,Andreas T.
编辑:我不得不改变问题文本中的内容:我改变了"能够用uint32计算画布点数"的假设"能够计算画布上的点数(或者要存储的坐标对的数量")通过uint32.我原来的问题没有多大意义,因为我有一个sqrt(max(uint32))xsqrt(max(uint32))大小的画布,它可以通过16位移位和OR进行唯一表示.
我希望这是可以的,因为所有答案仍然对更新的假设最有意义
对不起.
考虑以下对象:
class Route
{
public int Origin { get; set; }
public int Destination { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
Route实现了相等运算符.
class Routing
{
public List<Route> Paths { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我使用下面的代码为Routing对象实现GetHashCode方法,它似乎工作,但我想知道这是否是正确的方法呢?我依靠平等检查,因为我不确定我以为我会问你们.我可以只是总结哈希码还是我需要做更多的魔术以保证所需的效果?
public override int GetHashCode() =>
{
return (Paths != null
? (Paths.Select(p => p.GetHashCode())
.Sum())
: 0);
}
Run Code Online (Sandbox Code Playgroud)
我GetHashCode()在这里检查了几个问题,以及MSDN和Eric Lippert关于这个主题的文章,但是找不到我想要的东西.
在本文中,Jon Skeet提到他通常使用这种算法来覆盖GetHashCode().
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
// Suitable nullity checks etc, of course :)
hash = hash * 23 + Id.GetHashCode();
return hash;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我尝试使用它,但Resharper告诉我,方法GetHashCode()应该只使用只读字段进行散列(尽管编译很好).什么是好的做法,因为现在我真的不能让我的字段是只读的?
我尝试通过Resharper生成这个方法,这是结果.
public override int GetHashCode()
{
return base.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)
这没什么贡献,说实话......
我如何处理GetHashCode函数中的空字段?
Module Module1
Sub Main()
Dim c As New Contact
Dim hash = c.GetHashCode
End Sub
Public Class Contact : Implements IEquatable(Of Contact)
Public Name As String
Public Address As String
Public Overloads Function Equals(ByVal other As Contact) As Boolean _
Implements System.IEquatable(Of Contact).Equals
Return Name = other.Name AndAlso Address = other.Address
End Function
Public Overrides Function Equals(ByVal obj As Object) As Boolean
If ReferenceEquals(Me, obj) Then Return True
If TypeOf obj Is Contact Then
Return Equals(DirectCast(obj, Contact)) …Run Code Online (Sandbox Code Playgroud) 我认为标题非常清楚.
我在想,如果有使用的时候是有一定效率的开销IEqualityComparer在Dictionary<K,V>提供一个当这是如何工作的?
谢谢
c# ×7
gethashcode ×4
.net ×3
hash ×3
equality ×2
caching ×1
dictionary ×1
hashtable ×1
iequatable ×1
java ×1
null ×1
performance ×1
resharper ×1
vb.net ×1