IEqualityComparer' 1用于lambda表达式而不访问表达式

时间:2015-10-15 12:18:42

标签: c# lambda equality

给定lambda表达式,我需要一种方法将已编译的委托存储在字典中,因此我不需要每次都编译它们。

我的第一次尝试是通过表达式转换为string来缓存委托:

class ExpressionEqualityComparer : IEqualityComparer<Expression>
{
    public bool Equals(Expression a, Expression b)
    {
        return a.ToString().Equals(b.ToString());
    }
    public int GetHashCode(Expression e)
    {
        return e.ToString().GetHashCode();
    }
}
void Main()
{
    var e1 = (Expression<Func<object, string>>)(o => ((Model)o).Prop);

    Console.WriteLine(e1.ToString());

    d.Add(e1, e1.Compile());

    var e2 = (Expression<Func<object, string>>)(o => ((Model2)o).Prop);
    try
    {
        d.Add(e2, e2.Compile());
    }
    catch
    {
        // ArgumentException. An element with the same key already exists in the Dictionary< TKey, TValue >.
    }
    Console.WriteLine(e2.ToString());   
    Console.WriteLine(d.Count);
}
Dictionary<Expression, System.Func<object, string>> d = new Dictionary<Expression, System.Func<object, string>>(new ExpressionEqualityComparer());
class Model
{
    public string Prop { get; set; }
}
class Model2
{
    public string Prop { get; set; }
}

输出:

o => Convert(o).Prop
o => Convert(o).Prop
1

这种方法不起作用,因为Expression.ToString()不够详细,无法提供相等性,而且它不可靠,因为一般不保证ToString实现。

如何在不访问表达式节点的情况下正确实现Equals(Expression, Expression)GetHashCode(Expression)

如果表达式实例无法实现,是否可以使用其他语言构造,包装原始表达式,可用于获取所述表达式?

绝对要求,这使得这个问题与重复不同: 在与表达式的平均大小成比例的恒定摊销时间内工作,这是保持原始散列函数算法属性的要求。

0 个答案:

没有答案