SortedBindingList DateTime Nulls

SortedBindingList DateTime Nulls

Old forum URL: forums.lhotka.net/forums/t/2785.aspx


johnallenids posted on Thursday, April 26, 2007

I am looking for the best way to expose a DateTime field in a read-only child object contained in a read-only list; the DateTime field is not a required field; the list must be displayed in a DataGridView; the DateTime column must be sortable in the grid.

Then I tried to expose it as a read-only property of type object; if the value was empty, I returned DBNull.Value; if the value was not empty, I returned the DateTime value. However, the SortedBindingList threw an exception on sorting: "Object must be of type DateTime"

Is there a better way to do this?

John

RockfordLhotka replied on Thursday, April 26, 2007

You might consider making your property be a Nullable<DateTime>. I'm not entirely sure SortedBindingList will like that, as I haven't tried it, but at least you'd be using a consistent type.

xal replied on Thursday, April 26, 2007

Rocky,

Now that we're on this subject, would it hurt to expose a Nullable<DateTime> in SmartDate ??
That would make it even more flexible.


Andrés

johnallenids replied on Monday, April 30, 2007

The CompareTo method returns an incorrect value when the Key value is null but the target value is not null; if the Key value is null, zero will always be returned. If I'm not mistaken, it should return zero if both Key and target are null, but return -1 if Key is null but target is not null.

John

RockfordLhotka replied on Monday, April 30, 2007

You may be right, but I need to ask: on what you do base that assertion?

Technically comparing anything to a null should result in a null result. A null is never < or > any other value - the comparison itself is not valid.

In SortedBindingList however, I didn't want to just throw a null reference exception (which is the "correct" thing to do) because I felt that would degrade the value of the list class.

So instead, I opted to say that if null compared to anything is null, then null=anything. That was an arbitrary decision on my part.

I am guessing here, that the suggestion that null<anything is equally arbitrary. It may be a better option, but it needs consideration, because it could break existing code.

Or perhaps there's some authority or some similar scenario where null<anything, and that would be nice, because then we'd move from the realm of arbitrary choices to at least basing the decision on precident.

johnallenids replied on Monday, April 30, 2007

I'm not sure if I'm right; I'm only basing this on what I've tested with the Nullable<DateTime> type. Comparing a valid DateTime value to a null returns 1:

Nullable<DateTime> myDate = DateTime.MinValue;

int comparison = ((IComparable)myDate).CompareTo(null);

//comparison is equal to 1

So I made the (probably naiive) assumption that if a valid DateTime value was greater than  null, than a null would be less than a valid DateTime.

I don't believe the current code will correctly sort a Nullable<DateTime> column, because the CompareTo method as it is currently implemented returns inconsistent results when comparing a null Key to a DateTime target vs. comparing a DateTime Key to a null target.

 

RockfordLhotka replied on Monday, April 30, 2007

Ahh, excellent, thank you!

Given that evidence I think you have identified a bug, so I'll add this to the wish list of things to be fixed/changed.

johnallenids replied on Monday, May 07, 2007

I had a look at the CompareTo method code in the repository; if I'm not mistaken, this still will not sort a <Nullable>DateTime type correctly, because it will not return zero if both Key and target are null. Here's the code I'm currently using:

public int CompareTo(ListItem other)

{

object target = other.Key;

if (Key is IComparable)

return ((IComparable)Key).CompareTo(target);

else

{

if (Key == null && target == null)

return 0;

else if (Key == null && target != null)

return -1;

else if (Key.Equals(target))

return 0;

else

return Key.ToString().CompareTo(target.ToString());

}

}

RockfordLhotka replied on Monday, May 07, 2007

True, but I don’t think it matters. If null<null then they’ll get put in that order, but regardless, all null values will end up <”anything else” so they’ll always sort properly relative to any real value.

 

But there could be perf issues with some sort algorithms that could be avoided if null=null, so your change is a good one.

 

Rocky

 

From: johnallenids [mailto:cslanet@lhotka.net]
Sent: Monday, May 07, 2007 12:20 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] SortedBindingList DateTime Nulls

 

I had a look at the CompareTo method code in the repository; if I'm not mistaken, this still will not sort a <Nullable>DateTime type correctly, because it will not return zero if both Key and target are null. Here's the code I'm currently using:

public int CompareTo(ListItem other)

{

object target = other.Key;

if (Key is IComparable)

return ((IComparable)Key).CompareTo(target);

else

{

if (Key == null && target == null)

return 0;

else if (Key == null && target != null)

return -1;

else if (Key.Equals(target))

return 0;

else

return Key.ToString().CompareTo(target.ToString());

}

}



No virus found in this incoming message.
Checked by AVG Free Edition.
Version: 7.5.467 / Virus Database: 269.6.5/792 - Release Date: 5/6/2007 9:01 PM

RockfordLhotka replied on Monday, May 14, 2007

OK, I have updated the svn code in a similar manner, so hopefully we’re set now.

 

Thanks, Rocky

 

From: johnallenids [mailto:cslanet@lhotka.net]
Sent: Monday, May 07, 2007 12:20 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] SortedBindingList DateTime Nulls

 

I had a look at the CompareTo method code in the repository; if I'm not mistaken, this still will not sort a <Nullable>DateTime type correctly, because it will not return zero if both Key and target are null. Here's the code I'm currently using:

public int CompareTo(ListItem other)

{

object target = other.Key;

if (Key is IComparable)

return ((IComparable)Key).CompareTo(target);

else

{

if (Key == null && target == null)

return 0;

else if (Key == null && target != null)

return -1;

else if (Key.Equals(target))

return 0;

else

return Key.ToString().CompareTo(target.ToString());

}

}



No virus found in this incoming message.
Checked by AVG Free Edition.
Version: 7.5.467 / Virus Database: 269.6.5/792 - Release Date: 5/6/2007 9:01 PM

RockfordLhotka replied on Tuesday, May 01, 2007

You are suggesting always exposing the Date property as a Nullable(Of DateTime)?

 

 

 

From: xal [mailto:cslanet@lhotka.net]
Sent: Thursday, April 26, 2007 3:25 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] SortedBindingList DateTime Nulls

 

Rocky,

Now that we're on this subject, would it hurt to expose a Nullable<DateTime> in SmartDate ??
That would make it even more flexible.


Andrés


xal replied on Tuesday, May 01, 2007

Well, changing the Date property could break code. I was suggesting another property like "NullableDate" to be exposed. That wouldn't hurt, would it?

Andrés

RockfordLhotka replied on Tuesday, May 01, 2007

I’m not sure. I’d have to store the value internally as a Nullable<DateTime> or I couldn’t support that new property. So then I’d have to figure out how to covert Nullable<DateTime> to DateTime in order to keep the existing Date property functioning. So what does a null translate to?

 

Also, though this wouldn’t “hurt” exactly, you are talking about nearly doubling the number of constructors, conversion methods and so forth, because they’d all have to somehow support both DateTime and Nullable<DateTime> parameters and return types (if that’s even possible).

 

Rocky

 

 

From: xal [mailto:cslanet@lhotka.net]
Sent: Tuesday, May 01, 2007 11:31 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: SortedBindingList DateTime Nulls

 

Well, changing the Date property could break code. I was suggesting another property like "NullableDate" to be exposed. That wouldn't hurt, would it?

Andrés


Copyright (c) Marimer LLC