Why not SmartInt, etc.?

Why not SmartInt, etc.?

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


david.wendelken posted on Tuesday, July 25, 2006

The smart date class is pretty neat. 

Isn't there a need for a SmartInt, SmartDecimal, etc., that can handle nulls as gracefully?

Has anyone tried doing that?

ajj3085 replied on Tuesday, July 25, 2006

I haven't done it, but I believe others have done SmartBool.  There's no reason you can't make those classes, they should be very easy to build.  If you have a need, certainly go ahead and build them.

RockfordLhotka replied on Tuesday, July 25, 2006

Though if you goal is merely to allow data binding to work with null values, then you can use Nullable<T> (or int? in C#). Binding still doesn't work right without some help, but this blog entry points to a solution from some guys in Norway

http://www.lhotka.net/weblog/ExtendingControlsToHandleNullableTypes.aspx

SonOfPirate replied on Tuesday, July 25, 2006

What a timely post.  This is actually what brought me to the forum today.  Is databinding to a Windows Form control the only limitation to using System.Nullable<T>?

I have lost hair over the last few years dealing the need to have a "not set" indicator for various properties that are of primitive types (int, bool, etc.).  Easy enough with enumerations to add a NotSet value, but how to deal with this with a ValueType?  SmartDate accomplishes this but I've never been completely comfortable with using the MinValue/MaxValue to indicate 'null'.  System.Nullable<T> seems like a great way around this and I have already put it in place with some custom configuration file stuff where I only want to reset the programmed defaults if the value was actually entered into the config file.

For those of you who have not lost sleep along with me deciphering the new System.Configuration classes, when you create a custom element, for instance, you define the type of the attribute and a default value when you construct the custom element.  A nice feature of these classes is that the object graph is created even if the entries don't exist in the config file.  In this case, each property/attribute will be given the default value that you defined in the constructor.  And, in a typical implementation, these config settings are mapped to some other object that is a "normal" component of your application.  So, issue #1 with all of this is that your default value is defined in two places!!!  Never a good thing.  Issue #2 is that it is preferable to only set the value from the config file if it was actually defined in the file.  Unless you have some way of determining this, your SOL.

Enter System.Nullable<T>.

In all of our custom config classes, we've replace primitive value types with System.Nullable<valuetype> and a default value of 'null'.  Then in the code the maps the config settings to our objects, we test the HasValue property to detect if the setting was actually in the config file.  This works great because now we can change our default values in one place and not have to worry about collateral affects.  In addition, we have avoided the MinValue/MaxValue scenario (which doesn't work with boolean types!?!?!).

So, why not use System.Nullable<T>?  And why not implement SmartDate as System.Nullable<System.DateTime> and eliminate the MinValue/MaxValue issue?  I know the issues with formatting, parsing and comparing that are mentioned in the book and am not suggesting that we completely throw out SmartDate.  What I mean is, could there be a compromise that takes the behavior/implementation of System.Nullable and the benefits of delegation from SmartDate to create a better...NullableDate?

I guess I'm wondering what is really under-the-hood of System.Nullable?  Isn't it really doing the same thing SmartDate is as far as delegation goes?  And, wouldn't a null value be reflected by not having a reference to the internal object to delegate to?  However, in trying to implement this, we would be back to the same problem with value types - how do we know that the internal variable is null?  In other words, we'd have something like:

public class NullableDate
{
    private DateTime value;

    public System.Boolean HasValue
    {
        get
        {
            return (value != null);
        }
    }
}

Won't work!

Does default(T) somehow make this work?  So, if we had this instead:

public class NullableDate<T>
{
    private T value;

    public System.Boolean HasValue
    {
        get
        {
            return (value != default(T));
        }
    }
}

Would we have System.Nullable???

Thanks for letting me vent...

RockfordLhotka replied on Tuesday, July 25, 2006

If it helps, you can create a Nullable<SmartDate>   :)
 
Rocky

RockfordLhotka replied on Tuesday, July 25, 2006

But one other thing about SmartDate - and this was the clincher for me in terms of keeping it in the framework:
 
When it comes to dates, "empty" and "null" are not the same thing. There are very clearly defined semantics about what happens when you compare anything to null - the result is ALWAYS null. Nullable<T> helps with this - in that they preserve the null semantics (at least in C#).
 
But I have worked on many, many applications where an empty date can be compared to a real date. And the result isn't null - it is a valid boolean result. Nullable<T> doesn't help with this at all, because it merely does null propogation - which is totally useless.
 
Now it might be possible to create an Empty<T> - I haven't had time to give that a lot of thought. But even if you did that, you'd lose the special parsing and formatting capabilities offered by SmartDate.
 
So for me, the "empty" concept was the driver for keeping SmartDate in the framework, and the remaining features just support that decision.
 
Rocky

david.wendelken replied on Tuesday, July 25, 2006

I spent about 30 minutes cloning SmartDate into SmartInt this afternoon.

I'll be testing it over the next week, and will post it if it works out. 

Rocky, would you like to add them to the framework if we supply them?  I would think they would be very stable over time, thus requiring little to no maintenance on your part... :)

 

RockfordLhotka replied on Tuesday, July 25, 2006

I appreciate the thought. Unfortunately at this time I don't have a mechanism by which I can accept code from external sources into the framework. The problem rests with IP ownership - I'd need to have you sign an agreement granting me the code. This is something I've considered putting together (because you aren't the first to want to contribute code), but haven't done thus far.
 
Rocky


From: david.wendelken [mailto:cslanet@lhotka.net]
Sent: Tuesday, July 25, 2006 8:21 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: Why not SmartInt, etc.?

I spent about 30 minutes cloning SmartDate into SmartInt this afternoon.

I'll be testing it over the next week, and will post it if it works out. 

Rocky, would you like to add them to the framework if we supply them?  I would think they would be very stable over time, thus requiring little to no maintenance on your part... :)

 




david.wendelken replied on Tuesday, July 25, 2006

The DotNetNuke project has a pretty reasonable one that protects the interests of all parties.

Want a copy of it to look at?

RockfordLhotka replied on Tuesday, July 25, 2006

Sure, can't hurt.


From: david.wendelken [mailto:cslanet@lhotka.net]
Sent: Tuesday, July 25, 2006 9:33 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: RE: Why not SmartInt, etc.?

The DotNetNuke project has a pretty reasonable one that protects the interests of all parties.

Want a copy of it to look at?




ajj3085 replied on Wednesday, July 26, 2006

You could start a project on CslaContrib and add the code there.

Copyright (c) Marimer LLC