Using the expression <Func <object> as a key in a dictionary

How can I use expression type> as a key in a dictionary?

I just started playing with Expression instances and I'm not sure what I want to do is possible.

It seems that two identical expressions are not equal, as when I try, I can put the entry in the dictionary using the expression as a key, but it returns false when I ask the dictionary if it contains a key if I do not use the same instance of the expression .

TypeToTest test = new TypeToTest();
Expression<Func<object>> expression = ()=>test.PropertyA;
IDictionary<Expression<Func<object>>,bool> dictionary = new Dictionary<Expression<Func<object>>, bool> ();
dictionary[expression] = true;
Assert.That (dictionary.ContainsKey(expression), Is.True);
Assert.That (dictionary.ContainsKey(()=>test.PropertyA), Is.True);

the last line above fails if I want it to succeed.

The goal is to be able to define a set of rules that apply to the properties or methods of an object, so I can determine, for example, if a property is editable or if a value with a specific key in the dictionary can be deleted. I don’t want to have an object flag that determines whether it is editable (since variability may differ for different properties), and another - whether it is removable, but rather another class that will be responsible for maintaining the associated rules with the object, so that as the object expands in the future, additional rules may be added to describe the editable / accessibility / possibility of deletion / component parts of the object. if that makes sense.

, , , as, , , , .

, - ?

+3
2

, Equals IEquatable<T>. (, ToString()) , IMO a Expression .

ToString(); :

class Program {
    static void Main() {
        TypeToTest test = new TypeToTest();
        Expression<Func<object>> expression = () => test.PropertyA;
        IDictionary<Expression<Func<object>>, bool> dictionary =
            new Dictionary<Expression<Func<object>>, bool>(
               new ToStringComparer<Expression<Func<object>>>());
        dictionary[expression] = true;

        bool x = dictionary.ContainsKey(expression), // true
            y = dictionary.ContainsKey(() => test.PropertyA); // true
    }
}
class ToStringComparer<T> : IEqualityComparer<T> where T : class {
    public bool Equals(T x, T y) {
        if ((x == null && y == null) || ReferenceEquals(x,y)) return true;
        if (x == null || y == null) return false;
        return x.ToString() == y.ToString();
    }
    public int GetHashCode(T obj) {
        return obj == null ? 0 : obj.ToString().GetHashCode();
    }
}
+4

Expression Equals GetHashCode, . , ()=>test.PropertyA .

IEqualityComparer<Expression> . Equals GetHashCode, Expression .

+2

Source: https://habr.com/ru/post/1779990/


All Articles