Equality and Comparison Strategies

Dmitri Nesteruk
A free video tutorial from Dmitri Nesteruk
Software/Hardware Engineering • Quant Finance • Algotrading
4.4 instructor rating • 21 courses • 122,343 students

Lecture description

The .NET BCL uses the Strategy pattern for custom equality and comparison operations.

Learn more from the full course

Design Patterns in C# and .NET

Discover the modern implementation of design patterns with C# and .NET

17:57:13 of on-demand video • Updated May 2020

  • Recognize and apply design patterns
  • Refactor existing designs to use design patterns
  • Reason about applicability and usability of design patterns
English [Auto] So one location where the strategy pattern is used quite a lot is when it comes to quality and comparison in the Dot Net framework. So let me show you a very simple example let's suppose that you have a class called Person so you have a class called Person. Let's suppose that there is just a bunch of fields. So we have met maybe some identifier like you would have a primary key and a database. You also have a person's name and you can also define for example a person's age like so. So we can make a constructor which Initialize all of these. And let's imagine that we have a list of people so we have var people equals new list of person. Let's suppose that we got the data from a database and now we want to for example sort this list so I can say people people sorts. And what do you think would happen here. Right out of the box the answer is nothing. The answer is that here when we do the kind of sorting without specifying what we're sorting by we're not really going to get any results. We're going to get the default array that sort implementation because that's what a list will actually do behind the scenes it will go to array that saw it so we're not going to get anything because at the moment that that framework doesn't really know how to sort of person objects. We have to give it a strategy for how to do that. Now there are two ways of doing it. You can specify the default strategy for all types. All all instances of class plus and you can specify the default strategy or you can specify custom strategy. So if you want the default strategy just go and use your idea or whatever idea you use and what you want to generate is you want to generate relational members. So in this case I want to use the idea for the actual implementation so I want to use the idea feel then after I generate code you can see that I get like lots of stuff. So suddenly my passing class becomes an icon parable of person. It also becomes just ordinary I comparable the kind of weekly type version and then I get lots of generate code for first of all compare to. So remember compared to something that is basically going to return an ordering relation. So it compares the ideas because that's what I specified. So it does idea though compared to other dot idea and is going to return negative one zero all positive one depending on the ordering relationship between the idea of the current element and the idea of the other elements we're comparing to. So if it gets minus one that means the first is less than the second if it gets a zero. That means they're equal if it gets a one. That means that the second is greater than the first. So then we have the Weekly Times version you can see that there's plenty of scaffolding here. There's also time checks because it's weakly typed. You have to basically cast it to the right thing and then you sort of you throw an exception if that doesn't that doesn't match what you were looking for in the first place and then you have the relation operators like less than greater than less than or equal greater than or equal. These are all automatically generated for you. So as soon as we've done this people dot sort now takes a meaning when you say people dot sort you are now sorting by I.D.. Of course what you can do is you can be explicit about it. You can say that well we are in fact sorting by idea and you can sort by other criteria as well. So for example I can say people dot sort. And here I have lots of options of what to specify So for example I can specify and I compare which is just a delegate. So here I can specify a lamb that which takes two people x and y and it basically returns the comparison of their name so I can say X not name and then compare to y don't name. That way we're actually going to sort by name as you can see it's a rather long winded kind of thing. Typically you'd use link and in link you would just say get use the name file for actual sorting. So this is a somewhat long winded. This is not the link sort. This is the sort that's built into the list type. But what about strategies. What about the different strategies that I use so here. This is kind of the default strategy the default strategy is just to compare objects using relational operators and we've defined lots of them up here we've defined all of these things with defined compare to. And so now this this approach people that source is going to use the idea by default here we're specifying this strategy as a lambda we're basically saying this is the strategy that we want to use in the sorting process. What you can also do is you can use the cogeneration facilities of whatever i.e. using to generate additional compares. So here we've made a default compare which compares by idea but we can make additional compares which compare by name for example. So here once again sort of behind the scenes I'm using the cogeneration facilities for a relational compare. I'm specifying the name as a comparison here I get some generated so here you can see that we get plenty more generated code so we generate a sealed class called name relational compare and all it does is it implements and I compare off person and then you have a public and compare method which compares to people X and Y as you can see here and then it goes through the motions comparing the actual strings kind of like what I'm doing down here except that I'm not using the audio comparison so here I'm using compare to which is actually culture specific so that can backfire on you and down here what you can see is we also have a static member which exposes the compare as a static member. This is just a usability thing basically. So what you can now write is instead of writing this what you can say is you can say people sort person not named compare and this is once again going to sort by name by comparing people's names. So in all of these cases you're using strategies. So in people that sort you using kind of the default strategy the one that's provided automatically either in the class or if you forgot to actually generate it it's just going to use the default approach which isn't really useful because it's probably going to look at memory addresses of objects or something because there is no real information that can be used for for the purposes of sorting. So the second one is where the strategy is provided by a lambda and here with specified the lambda to be useful comparison this is actually if you're thinking about link operators then every single link operator is effectively fed a strategy that it subsequently adapts to finding for example unique objects by a certain field and so on. And finally what we've done here is a bit of a utility so here what we've done is we've generated additional you know classes. So here is the name relational compare class so we've generated an additional class which is subsequently exposed as a static member and this is once again a strategy. So it doesn't have the what strategy in its name but you know it's a strategy is a strategy for comparing objects using the name field as the discriminator as the part that you're actually comparing. So this is how the Net framework uses the strategy pattern to perform comparisons. And of course the same goes for equality. So here we've talked about things like I can parable but here similarly you would have I equate it will and then you would have equality strategies when looking for distinct objects for example looking for objects with unique names so unique ideas for example you would have a and I equate table and you would use that to compare the objects. So that's how that framework actually uses the strategy pattern.