Mar*_*cek 113 c# unique hashcode gethashcode
有没有办法获取实例的唯一标识符?
GetHashCode()对于指向同一实例的两个引用是相同的.但是,两个不同的实例可以(很容易)获得相同的哈希码:
Hashtable hashCodesSeen = new Hashtable();
LinkedList<object> l = new LinkedList<object>();
int n = 0;
while (true)
{
object o = new object();
// Remember objects so that they don't get collected.
// This does not make any difference though :(
l.AddFirst(o);
int hashCode = o.GetHashCode();
n++;
if (hashCodesSeen.ContainsKey(hashCode))
{
// Same hashCode seen twice for DIFFERENT objects (n is as low as 5322).
Console.WriteLine("Hashcode seen twice: " + n + " (" + hashCode + ")");
break;
}
hashCodesSeen.Add(hashCode, null);
}
Run Code Online (Sandbox Code Playgroud)
我正在编写一个调试插件,我需要获取某种ID作为参考,这在程序运行期间是唯一的.
我已经设法获得实例的内部ADDRESS,这是唯一的,直到垃圾收集器(GC)压缩堆(=移动对象=更改地址).
Stack Overflow问题Object.GetHashCode()的默认实现可能是相关的.
这些对象不受我的控制,因为我正在使用调试器API访问正在调试的程序中的对象.如果我控制对象,添加我自己的唯一标识符将是微不足道的.
我想要用于构建哈希表ID - >对象的唯一ID,以便能够查找已经看过的对象.现在我解决了这个问题:
Build a hashtable: 'hashCode' -> (list of objects with hash code == 'hashCode')
Find if object seen(o) {
candidates = hashtable[o.GetHashCode()] // Objects with the same hashCode.
If no candidates, the object is new
If some candidates, compare their addresses to o.Address
If no address is equal (the hash code was just a coincidence) -> o is new
If some address equal, o already seen
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*Jon 69
好消息,大家好!
这项工作的完美工具是在.NET 4中构建的,它被称为ConditionalWeakTable<TKey, TValue>.这个班:
Jon*_*eet 40
引用是对象的唯一标识符.我不知道有什么方法可以将它转换成类似字符串等的东西.在压缩过程中引用的值会发生变化(正如你所见),但是每个先前的值A都会变为值B,所以到目前为止就安全代码而言,它仍然是一个唯一的ID.
如果涉及的对象在您的控制之下,您可以使用弱引用(以避免垃圾回收)创建映射,从而引用您选择的ID(GUID,整数,等等).然而,这会增加一定的开销和复杂性.
sis*_*sve 40
检查出ObjectIDGenerator类?这就是你想要做的,以及Marc Gravell所描述的.
ObjectIDGenerator跟踪先前识别的对象.当您询问对象的ID时,ObjectIDGenerator会知道是返回现有ID,还是生成并记住新ID.
这些ID在ObjectIDGenerator实例的生命周期中是唯一的.通常,ObjectIDGenerator的生命周期与创建它的Formatter一样长.对象ID仅在给定的序列化流中具有意义,并且用于跟踪哪些对象在序列化对象图中具有对其他对象的引用.
使用哈希表,ObjectIDGenerator保留将哪个ID分配给哪个对象.唯一标识每个对象的对象引用是运行时垃圾收集堆中的地址.对象引用值可以在序列化期间更改,但表会自动更新,以便信息正确.
对象ID是64位数字.分配从一开始,因此零永远不是有效的对象ID.格式化程序可以选择零值来表示其值为空引用的对象引用(在Visual Basic中为Nothing).
Ant*_*lev 35
RuntimeHelpers.GetHashCode()可能有帮助(MSDN).
你可以在一秒钟内开发自己的东西.例如:
class Program
{
static void Main(string[] args)
{
var a = new object();
var b = new object();
Console.WriteLine("", a.GetId(), b.GetId());
}
}
public static class MyExtensions
{
//this dictionary should use weak key references
static Dictionary<object, int> d = new Dictionary<object,int>();
static int gid = 0;
public static int GetId(this object o)
{
if (d.ContainsKey(o)) return d[o];
return d[o] = gid++;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以选择自己拥有的唯一ID,例如System.Guid.NewGuid(),或者只是整数以便最快地访问.
小智 6
这个方法怎么样:
将第一个对象中的字段设置为新值.如果第二个对象中的相同字段具有相同的值,则它可能是相同的实例.否则,退出不同.
现在将第一个对象中的字段设置为不同的新值.如果第二个对象中的相同字段已更改为不同的值,则它肯定是同一个实例.
不要忘记在退出时将第一个对象中的字段设置回原始值.
问题?
可以在 Visual Studio 中创建唯一的对象标识符:在监视窗口中,右键单击对象变量并从上下文菜单中选择“创建对象 ID ”。
不幸的是,这是一个手动步骤,我不相信可以通过代码访问标识符。
| 归档时间: |
|
| 查看次数: |
105303 次 |
| 最近记录: |