public class Filter
{
    public int A { get; set; }
    public int B { get; set; }
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
}

What is the best way, to compare two Filter objects according with sometimes one, and sometimes all properties? I mean I have Dictionary<Filter, string> and I need find all KeyValuePairs compatibile with used filter, e.g:

var f1 = new Filter(){A = 1}
var f2 = new Filter(){A = 1, Start = DateTime.Now, End = DateTime.AddHour(2)}

var dict = new Dictionary<...>()
dict.Add(new Filter(){A = 1}, "asdf");
dict.Add(new Filter(){A = 1}, Start = DateTime.Now.AddHours(-1), "qwerty");

Now usigng f1 I'd like find both KeyValuePairs, but using f2 I'd like to find only first KVP, because of Start in second object doesn't fulfill condition Start + End from f2 (it is outside the scope)

EDIT Dictionary is outside of the scope of this question. It has to be. I need only mechanism of the comparing. I don't create dictionary to do it. I need it to store some data important for me.

有帮助吗?

解决方案

How about something like this:

    IEnumerable<KeyValuePair<Filter, string>> DoIt(Dictionary<Filter, string> dict, Filter f)
    {
        return dict.Where
            (d => 
                (f.A == null || d.Key.A == f.A) && 
                (f.B == null || d.Key.B == f.B) && 
                (f.Start == null || f.Start < d.Key.Start) /* && Condition for End */);
    }

I think the condition is not exactly what you wanted, but you'll probably be able to figure it out from here...

其他提示

Can you use the IComparable interface to achieve what you need?

See http://msdn.microsoft.com/en-us/library/system.icomparable.aspx for more details.

If you need to compare by multiple criteria, one Dictionary<Filter, string> will not be enough. You can supply a custom IEqualityComparer<Filter> when instantiating it, but it will only allow you to define a single comparison criteria.

The point of the dictionary is to allow fast lookup by a certain key, and you won't be able to benefit from this if you want your key to change.

You can either:

  1. Create a new dictionary instance for each criteria you are planning to use, and pass the appropriate IEqualityComparer<Filter> implementation, or

  2. Use a plain List<Tuple<Filter, string>> and then filter it using IEnumerable.Where.

First. You cannot use dictionary for this. Dictionary only works when you have one way to compare keys. And that is through GetHashCode and Equals overrides of said key object.

If you want to compare two objects, you can implement an IComparer class, that has parameters on which will compare different properties.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top