# Value comparison in sorting a generic list class

G

#### Guest

I have created a small program that illustrates the problem. I would know how
to address the fields that I want to sort on in the greaterThan comparison.
Anybody who knows??

using System;

class Program
{
public List<item> itList, index1;

public class List<T>
{ T[] items;

public List(int capacity)
{ items = new T[capacity];
}

public T this[int index]
{ get { return items[index]; }
set { items[index] = value; }
}

static bool greaterThan(T a, T b)
{ return (a.x > b.x); // 1. How to do this?
} // 2. And a flexible assignment of x or y

public void swap(int i, int j)
{ T temp = this;
this = this[j];
this[j] = temp;
}

public void Bubblesort()
{ Boolean noswap = false;
while (!noswap)
{ noswap = true;
for (int i = 0; i < this.items.Length - 1; i++)
{ if (greaterThan(this, this[i + 1]))
{ this.swap(i, i + 1);
noswap = false;
}
}
}
}
}

public class item //struct or class whatever
{ public double x, y;
public item(double x, double y)
{ this.x = x;
this.y = y;
}
public double fieldx() {
return this.x;
}
}

static void Main(string[] args)
{ List<item> itList = new List<item>(99);
Random RandObj = new Random();
for (int i = 0; i < 99; i++)
{ itList = new item(RandObj.NextDouble() * 100,
RandObj.NextDouble() * 100);
}
List<item> index1 = new List<item>(99);
for (int i=0;i<99;i++){index1=itList;}
index1.Bubblesort();
}
}

P

#### Peter Duniho

GB said:
I have created a small program that illustrates the problem. I would know how
to address the fields that I want to sort on in the greaterThan comparison.
[...]
static bool greaterThan(T a, T b)
{ return (a.x > b.x); // 1. How to do this?
} // 2. And a flexible assignment of x or y

The answer depends on what exactly you're trying to achieve.

The most straightforward answer is to constrain the class T to implement
IComparable, and then use the Compare method. In the
IComparable.Compare method, that's where you'd write the actual
comparison using the specific fields. This is how existing .NET classes
do it (well, it's one way they offer...you can often also instead
implement an IComparer class that does the same thing, but doesn't
require changing the compared class itself).

But your question implies that you really want the generic class to know
about the fields in question. AFAIK, you can't do that exactly, not
with fields. However, you could create a custom interface that defines
a property to be used in the comparison, and then again using a
constraint for the generic class's type, require T to implement that
interface. Then in the greaterThan() method you can use the property
you declared in the interface.

If the above doesn't answer the question, you may want to elaborate on
what behavior exactly you're trying to achieve. Your question is asking
for a specific implementation, but it may be that talking about what the
actual end goal is would be more productive.

Pete

M

#### Marc Gravell

First - why write your own List<T> - is this just for academic
purposes?

However, the simplest (and most appropriate) approach would be for you
Sort() [or BubbleSort()] method to accept either an IComparer<T>, or a
Comparison<T>. This allows the external caller to control the sort
(i.e. greaterThan is owned by the caller, not the list). A similar
example is here: http://msdn2.microsoft.com/en-us/library/w56d4y5z.aspx

This also allows for very tidy inline usage - i.e.

myList.Sort(delegate(Item lhs, Item rhs) {return int.Compare(lhs.x,
rhs.x);});

this will probably get even tidier in 3.5 with lambda expressions.

Marc

J

#### Jon Skeet [C# MVP]

I have created a small program that illustrates the problem. I would know how
to address the fields that I want to sort on in the greaterThan comparison.
Anybody who knows??

Either add a constraint on T that it must implement IComparable<T>, or
use Comparer<T>.Default.Compare.

Jon