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
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
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.
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.
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.
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());}
}
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
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
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
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