Icomparer and Nullable field

T

tshad

Using VS 2005, I have list that I want to sort that has a nullable field.

I am getting an error:

'System.Nullable<int>' does not contain a definition for 'CompareTo'

I am getting an error on the "secondInstance test for ProjectTableID, which
is a nullable int (int?).

public class RacerComparer : IComparer<FieldName>
{
public int Compare(FieldName firstInstance, FieldName
secondInstance)
{
int result = 0;
result =
firstInstance.ProcessOrder.CompareTo(secondInstance.ProcessOrder);
if (result != 0) return (result); // if not equal, not need to
check Name
result =
secondInstance.ProjectTableID.CompareTo(secondInstance.ProjectTableID);
if (result != 0) return (result);
return result;
}
}

I can't even test for the null (HasValue), because I am getting the error on
the build.

How can I change this so that I don't get this error?

Thanks,

Tom
 
J

Jon Skeet [C# MVP]

tshad said:
Using VS 2005, I have list that I want to sort that has a nullable field.

I am getting an error:

'System.Nullable<int>' does not contain a definition for 'CompareTo'

I am getting an error on the "secondInstance test for ProjectTableID, which
is a nullable int (int?).

public class RacerComparer : IComparer<FieldName>
{
public int Compare(FieldName firstInstance, FieldName
secondInstance)
{
int result = 0;
result =
firstInstance.ProcessOrder.CompareTo(secondInstance.ProcessOrder);
if (result != 0) return (result); // if not equal, not need to
check Name
result =
secondInstance.ProjectTableID.CompareTo(secondInstance.ProjectTableID);
if (result != 0) return (result);
return result;
}
}

I can't even test for the null (HasValue), because I am getting the error on
the build.

How can I change this so that I don't get this error?

I'd personally use Comparer<T>.Default. That handles nulls with no
problems.
 
B

Ben Voigt [C++ MVP]

tshad said:
Using VS 2005, I have list that I want to sort that has a nullable field.

I am getting an error:

'System.Nullable<int>' does not contain a definition for 'CompareTo'

I am getting an error on the "secondInstance test for ProjectTableID,
which is a nullable int (int?).

public class RacerComparer : IComparer<FieldName>
{
public int Compare(FieldName firstInstance, FieldName
secondInstance)
{
int result = 0;
result =
firstInstance.ProcessOrder.CompareTo(secondInstance.ProcessOrder);
if (result != 0) return (result); // if not equal, not need
to check Name
result =
secondInstance.ProjectTableID.CompareTo(secondInstance.ProjectTableID);
if (result != 0) return (result);
return result;
}
}

I can't even test for the null (HasValue), because I am getting the error
on the build.

How can I change this so that I don't get this error?

You need to test HasValue first and then if both have values, call
GetValueOrDefault() and compare the results.
 
T

tshad

Jon Skeet said:
I'd personally use Comparer<T>.Default. That handles nulls with no
problems.

I found the problem.

I had to change:

secondInstance.ProjectTableID.CompareTo(secondInstance.ProjectTableID);

to

secondInstance.ProjectTableID.Value.CompareTo(secondInstance.ProjectTableID.Value);

and it worked fine.

I am not sure how I would do this with the Comparer<T>.Default using the
multiple field sorts.

Thanks,

Tom
 
R

Rene

You could also use the "Nullable" static class, this calss makes it easy to
compare nullable values so that you don't have to worry about nulls.

int result = Nullable.Compare<int>(val1, val2);



tshad said:
Jon Skeet said:
I'd personally use Comparer<T>.Default. That handles nulls with no
problems.

I found the problem.

I had to change:

secondInstance.ProjectTableID.CompareTo(secondInstance.ProjectTableID);

to

secondInstance.ProjectTableID.Value.CompareTo(secondInstance.ProjectTableID.Value);

and it worked fine.

I am not sure how I would do this with the Comparer<T>.Default using the
multiple field sorts.

Thanks,

Tom
 
T

tshad

tshad said:
I found the problem.

I had to change:

secondInstance.ProjectTableID.CompareTo(secondInstance.ProjectTableID);

to

secondInstance.ProjectTableID.Value.CompareTo(secondInstance.ProjectTableID.Value);

and it worked fine.

I am not sure how I would do this with the Comparer<T>.Default using the
multiple field sorts.

I am not sure how to use Comparer<T>.Default. Especially with multiple
field sorts.

I did get my multipe field sort to work with:
public class Racer
{
private string name;
public string Name { get { return name; } }
private string car;
public string Car { get { return car; } }
public Racer(string name, string car)
{
this.name = name;
this.car = car;
}
public override string ToString()
{
return name + ", " + car;
}

}

public class RacerCollection : List<Racer> { }

public class FindRacer
{
private string car;
public FindRacer(string car)
{
this.car = car;
}
public bool DrivingCarPredicate(Racer racer)
{
return racer.Car == car;
}
}

public class RacerComparer : IComparer<Racer>
{
public int Compare(Racer firstInstance, Racer secondInstance)
{
int result = 0;
result = firstInstance.Car.CompareTo(secondInstance.Car);
if (result != 0) return (result); // if not equal, not need to
check Name
result = firstInstance.Name.CompareTo(secondInstance.Name);
if (result != 0) return (result);
return result;
}
}

I was having a little problems with understanding how the IComparer or the
delegate works and I think I have it now.

racers.Sort... will go through the list doing the CompareTo as many times as
it needs to until the list is sorted. I assume it just works like a foreach
loop in a Do until loop. Something like

do
{
foreach (Racer r in RacerCollection)
{
CompareTo(...)
}
}while( hadASwitch

If you are just going to do a simple sort with one of the properties in the
class there is no reason to use IComparer. You can just do the following
with a delegate for whichever property you want to sort the list with:

racers.Sort(delegate(Racer r1, Racer r2) { return
r1.Name.CompareTo(r2.Name); });
or
racers.Sort(delegate(Racer r1, Racer r2) { return
r1.Car.CompareTo(r2.Car); });

If you need to do something special, such as a multiple field sort then you
need to set up a separate class to handle each type of sort you may need to
do (such as my RacerComparer() method above) and just call it with no
parameters:

racers.Sort(new RacerComparer());

I think that is how it works.

Thanks,

Tom
Thanks,

Tom
 
J

Jon Skeet [C# MVP]

I am not sure how to use Comparer<T>.Default. Especially with multiple
field sorts.

Doing multi-field sorts takes a little bit of work. I've got a class in
MiscUtil to make life a bit easier.
http://pobox.com/~skeet/csharp/miscutil
I was having a little problems with understanding how the IComparer or the
delegate works and I think I have it now.

racers.Sort... will go through the list doing the CompareTo as many times as
it needs to until the list is sorted. I assume it just works like a foreach
loop in a Do until loop. Something like

do
{
foreach (Racer r in RacerCollection)
{
CompareTo(...)
}
}while( hadASwitch

Well, not quite. It does whatever comparisons it needs, which depends
on the algorithm it uses.
If you are just going to do a simple sort with one of the properties in the
class there is no reason to use IComparer. You can just do the following
with a delegate for whichever property you want to sort the list with:

racers.Sort(delegate(Racer r1, Racer r2) { return
r1.Name.CompareTo(r2.Name); });
or
racers.Sort(delegate(Racer r1, Racer r2) { return
r1.Car.CompareTo(r2.Car); });

If you need to do something special, such as a multiple field sort then you
need to set up a separate class to handle each type of sort you may need to
do (such as my RacerComparer() method above) and just call it with no
parameters:

racers.Sort(new RacerComparer());

I think that is how it works.

Not really. You can do a multi-field sort with a Comparison delegate
too. You can build a delegate instance from the Compare method you've
already got.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top