【问题标题】:C#: Is it possible to use expressions or functions as keys in a dictionary?C#:是否可以将表达式或函数用作字典中的键?
【发布时间】:2009-07-15 13:54:30
【问题描述】:

使用Expression<Func<T>>Func<T> 作为字典中的键是否有效?例如缓存繁重计算的结果。

例如,稍微改变一下我的 different question 的基本缓存:

public static class Cache<T>
{
    // Alternatively using Expression<Func<T>> instead
    private static Dictionary<Func<T>, T> cache;
    static Cache()
    {
        cache = new Dictionary<Func<T>, T>();
    }
    public static T GetResult(Func<T> f)
    {
        if (cache.ContainsKey(f))
            return cache[f];

       return cache[f] = f();
    }
}

这还能用吗?

编辑:经过快速测试,看起来它确实有效。但我发现它可能更通用,因为它现在是每个返回类型一个缓存...不确定如何更改它以便不会发生...嗯

编辑 2: 不,等等……它实际上没有。好吧,对于常规方法,它确实如此。但不适用于 lambda。即使它们看起来相同,它们也会获得各种随机方法名称。哦,好c”,)

【问题讨论】:

  • 我不是。在我的另一个问题中弄清楚缓存的内容时,我只是偶然发现了这个想法并且很好奇:)
  • 对调查好奇心的奖励积分,但我真的看不出该技术有任何实际应用。另一方面,如果可行的话,这个想法确实具有很高的酷炫因素。
  • ...如果这个东西有一个确定性的结果,那就是。
  • 呵呵。不确定的结果确实会降低凉爽系数,是的:p

标签: c# caching dictionary lambda


【解决方案1】:

你可以使用任何类型的对象,只要它是一个实例。即使是代表,但我确实建议使用代表作为键,因为它们不是为此而设计的。我不确定独立创建的委托会产生相同的哈希码,即使它们可以进行比较(相等)也会更少。

【讨论】:

  • 看来你是对的,代表不能很好地处理密钥 =/
  • 代表按引用进行比较,而不是“结构上”。也就是说,碰巧调用相同代码但属于不同实例的两个委托将比较为不相等。
  • @Eric Lippert:所以我认为,当“结构”比较无意义时,这是一种自然的后备机制:)
  • 我认为在相同类/实例上调用相同方法的委托比较相等。我有限的测试似乎表明它们确实如此,并且 Reflector 在 Delegate.Equals 中显示了“结构”比较逻辑......
【解决方案2】:

这可能有点牵强,但使用动态语言运行时(IronPython 等),您绝对可以从字典中运行任意代码 sn-ps。

然后,您可以根据需要动态运行代码,第一次缓存结果,并将缓存的结果用于以后的所有调用。

如果你有很多计算,我敢打赌这最终会表现得很好。不过,这都是情境性的,我不确定你到底想要达到什么目的。 :)

【讨论】:

    猜你喜欢
    • 2014-04-14
    • 2016-01-25
    • 1970-01-01
    • 1970-01-01
    • 2013-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多