Reputation: 442
I have a custom generic array/container and it has a sort method:
public void Sort()
{
for (int i = 0; i < Count; i++)
{
int min = i;
for (int j = i + 1; j < Count; j++)
if (Items[j].CompareTo(Items[min]) < 0)
min = j;
if (min == i) continue;
T temp = Items[i];
Items[i] = Items[min];
Items[min] = temp;
}
}
Items is an array of T objects. T implements IComparable and has a CompareTo method:
public int CompareTo(object obj)
{
if (!(obj is Player))
return -1;
Player player = (Player)obj;
if (Name.CompareTo(player.Name) < 0)
return -1;
else if (Name.CompareTo(player.Name) == 0)
return LastName.CompareTo(player.LastName);
else
return 1;
}
Player class has 3 properties: Name, LastName and Score. This works fine to sort elements by name and last name, but now I need another container that should be sorted by score (a third property). How can I implement two different comparison methods without using List and built-in OrderBy, Sort methods?
Is it possible to pass class properties into the Sort method somehow?
Container<Player> sortedByName = playerList.Sort(Name, LastName);
Container<Player> sortedByScore = playerList.Sort(Score);
Upvotes: 0
Views: 1427
Reputation: 198324
Don't use IComparable
. This will create objects that know how to compare themselves, always using the same criterion.
Instead, make an external IComparer
- two, in fact! One that knows how to compare two players by names, and one that knows how to compare them by score.
You can see how to use it with standard Sort
here. Or you can put it to use in your own Sort
method, by replacing Items[j].CompareTo(Items[min])
with comparer.Compare(Items[j], Items[min])
Upvotes: 8
Reputation: 38757
You should implement an IComparer<T>
. You can then change your sort method to accept it:
public class PlayerNameComparer : IComparer<Player>
{
public int Compare(Player x, Player y)
{
if (x.Name.CompareTo(y.Name) < 0)
return -1;
else if (x.Name.CompareTo(y.Name) == 0)
return x.LastName.CompareTo(y.LastName);
else
return 1;
}
}
And the modified Sort method:
public void Sort(IComparer<Player> comparer)
{
for (int i = 0; i < Count; i++)
{
int min = i;
for (int j = i + 1; j < Count; j++)
if (comparer.Compare(Items[j], Items[min]) < 0)
min = j;
if (min == i) continue;
T temp = Items[i];
Items[i] = Items[min];
Items[min] = temp;
}
}
Example usage:
collection.Sort(new PlayerNameComparer());
collection.Sort(new ScoreComparer());
Upvotes: 3