1

我打算使用 ToString() 方法来创建缓存键。此缓存将用于缓存方法级别的调用,并且将使用参数名称和相应的值构造键。由于此缓存将为大型库构建,因此我无法确保每个方法都只有值类型参数或所有类都实现序列化。我需要在运行时确定对 ToString 的调用返回的是实际值而不是类型名称,以便可以禁止该方法调用参与缓存。

例如,考虑以下方法及其调用

AccountDetails GetDetails(int groupId, Account account)
{
    var ac1 = new Account( accountId = 123 };
    var ac2 = new Account( accountId = 555 };
    var return1 = GetDetails(15, ac1);
    var return2 = GetDetails(15, ac2);
}

在这种情况下,我会将缓存键构造为“groupId=15+account=namespace.Account”,从而导致不正确的冲突。如何在运行时检测到我对 account.GetString() 的调用将返回类型名称?

4

2 回答 2

3

您不应该将字符串用于一般缓存键。这真的不是ToString设计的目的。相反,您应该使用EqualsandGetHashCode来检查是否相等。当然,就像ToString,每个对象都有EqualsGetHashCode方法......但幸运的是,有一个IEquatable<T>接口提供了一个强烈的信号,表明一个类型真的为平等而设计的。

所以对于任何给定的类型X,只需检查该类型是否实现IEquatable<X>。如果是这样,那么用作缓存键应该是合理的。如果您正在编写通用方法,则可以强制执行此操作:

void Foo<T>(T key, /* other parameters */) where T : IEquatable<T>
于 2012-09-29T18:44:11.263 回答
0

我不知道“ToString”方法中的实现是什么(就你所知,有人在“Object”中重载了“ToString”,但实现方式与在“Object”中实现的方式相同)。

您不能将 ToString 用作对象的一种哈希。考虑两个逻辑上不同的对象,例如两个具有相同全名和不同 ID(或一些非 ascii 值,如图片)的“学生”对象。您需要使用真正的哈希 - 请参阅“GetHashCode”。

如果“GetHashCode”不是一个选项,我们将需要更多信息(比如“为什么”)

于 2012-09-29T17:07:01.893 回答