.net 在字典中使用可变对象作为键完全可以吗?

.net 在字典中使用可变对象作为键完全可以吗?,.net,dictionary,key,immutability,gethashcode,.net,Dictionary,Key,Immutability,Gethashcode,假设我有一个特殊的类,wrappedatatable,我想将每个wrappedatatable与一个DataTable关联起来。此外,对于任何给定的DataTable,我希望不存在超过一个wrappedatatable 一位同事建议我可以缓存我的wrappedatatable,并使用工厂方法访问一个,如下所示: public static class DataTableWrapper { private Dictionary<DataTable, WrappedDataTable&

假设我有一个特殊的类,
wrappedatatable
,我想将每个
wrappedatatable
与一个
DataTable
关联起来。此外,对于任何给定的
DataTable
,我希望不存在超过一个
wrappedatatable

一位同事建议我可以缓存我的
wrappedatatable
,并使用工厂方法访问一个,如下所示:

public static class DataTableWrapper
{
    private Dictionary<DataTable, WrappedDataTable> _wrappedTables;

    static DataTableWrapper()
    {
        _wrappedTables = new Dictionary<DataTable, WrappedDataTable>();
    }

    public static WrappedDataTable Wrap(this DataTable table)
    {
        WrappedDataTable wrappedTable;
        if (!_wrappedTables.TryGetValue(table, out wrappedTable))
            _wrappedTables[table] = wrappedTable = new WrappedDataTable(table);

        return wrappedTable;
    }
}
看看这个示例程序:

Dim comparer As IEqualityComparer(Of String) = New IdentityComparer(Of String)

Dim x As New String("Hello there")
Dim y As New String("Hello there")

Console.WriteLine(comparer.Equals(x, y))
Console.WriteLine(comparer.GetHashCode(x))
Console.WriteLine(comparer.GetHashCode(y))
输出:

False 37121646 45592480 假的 37121646 45592480
它不必返回唯一的值。它只需要返回一个不变的值,
object.GetHashCode
就是这样做的

只要
DataTable
不重写
Equals
GetHashCode
,您就基本上获得了相等的对象标识——这意味着对象是否发生了变异并不重要

就我个人而言,我希望看到
IEqualityComparer
的实现,它为任何类型提供身份平等,但我们自己无法实现这一点-如果没有被覆盖,无法找到
GetHashCode
将返回什么。(Java在其标准库中有此功能,但.NET没有.Grr。)


编辑:Woot-使用
对象.ReferenceEquals
运行时助手.GetHashCode()
,我们可以轻松实现
标识质量比较程序。耶

我认为你很了解事情。对于要存储在字典中的对象,任何会影响其哈希值或与其他对象相等性测试的特征都必须是不可变的。不会影响这些东西的特性不一定是不变的。

@Jon:像GetHashCodeBase一样?我承认我从来没有做过任何Java(nodatime是我第一次尝试,我一直在盯着代码看,而不是贡献)@Jeff:基本上是某种静态方法。在Java中是System.identityHashCode
@Jon:啊,听起来很有用。能够获得
ToString
Equals
的原始实现也会很有用,用于其他目的。@Jon:嘿,看看我的更新!这和你想要的一样吗? False 37121646 45592480