Why is SmartDate a struct instead of a class?

Why is SmartDate a struct instead of a class?

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


david.wendelken posted on Thursday, August 02, 2007

The following code works with SmartDate

SmartDate var = new SmartDate();
var.Text =
"04/01/1983";

Now, if I take a business object, called "Bo", and give it a SmartDate property like so:

private SmartDate _prop = new SmartDate();
public SmartDate Prop { set { _prop = value; } get { return _prop; } }

One would think this would work:

bo.Prop.Text = "04/01/1983";

But it doesn't, we get this error at compile time:

Cannot modify the return value of 'Bo.Prop' because it is not a variable.

After some research, it appears that if SmartDate was a class instead of a struct, the above code would work.

What do we gain by having SmartDate be a struct instead of a class, and what would break if it were changed to a class?

JoeFallon1 replied on Thursday, August 02, 2007

I believe Rocky has said many times that SmartDate is not supposed to be exposed directly as a Property - it is the backing field of a String Property.

This allows you to expose Strings to your UI and get and set them into the Smart Date field.

So your code should be:  BO.Prop = "04/01/1983"

As for it changing from Class to Structure - when it was first designed a few years ago, a CSLA user pointed out some advantages to the Structure and Rocky commented - "Why didn't I think of that?".

So he finally got around to changing it. (I don't recall what the advantages were though.)

Joe


 

RockfordLhotka replied on Thursday, August 02, 2007

No offense David, but this is really funny!!! Big Smile [:D]

SmartDate used to be a class, and I changed it to a value type in CSLA 2.0 because there was a lot of discussion by many people on the forum that pushed the change.

And they were right, btw, because DataTime is a value type, and SmartDate is trying to be as close to DateTime as possible while still providing its unique behaviors.

Ultimately though, Joe is right: SmartDate is designed to be used as a field, not a property, type. The idea is to expose a string property to allow the user to enter anything they want, and to use SmartDate behind the scenes to parse and process that input value.

david.wendelken replied on Thursday, August 02, 2007

Glad I could provide some amusement, I know laughs are in short supply in your neck of the woods this week. :(

I hadn't realized that DateTime is also a struct, and would therefore (presumably!) suffer from the same issues when used as a property.  Hmmm..

I knew you recommended exposing SmartDate variables as string properties.  Here's what motivated me to ask.

I've pretty much finished coding a web control I call DataBox, which is a CompositeControl that includes a TextBox and the ability to hold a collection of Validators.  DataBox has a set of custom properties such as Required, MaximumValue, MinimumValue, ValidationExpression, and DataType.  As the programmer fills in these properties, the DataBox automatically creates the appropriate validators with appropriate error messages, wires them up, etc.  It's a very handy control. :)

I'm now working on a subclass of DataBox called RuleBox.  This is the class I'm really excited about!
RuleBox has properties the programmer can set in order to identify which property in which business object the RuleBox represents.  If the page the RuleBox is placed on supports a custom interface, the RuleBox can interrogate its business object and get a list of broken rules for that property (for display to the user) along with any validator error messages.  What's more pertinent to my question is another capability it has, that of interrogating its business object for rules so that it can automatically set up appropriate validators for rules in the common rules library.   Of course, it can't do every rule, but I expect it to be able to handle 80% or more of the rules in an application.  If the underlying business object rules for that property change, the next time a user runs the page the RuleBox would automatically conform - at least for the rules it knows how to set up validators for.

However, if I expose my SmartDate, SmartInt16, SmartInt32, SmartDecimal, etc. variables as string properties, how would a general purpose RuleBox know what datatype to use when setting up the DataType and Range validators?  Reflection on the property won't help because it will just say it's a string!

The four ideas I've come up with are:
  1. Trust to naming conventions, and assume that a property named "EffectiveDate" will have an underlying private variable called _effectiveDate.  Use reflection to find out _effectiveDate's datatype.
  2. Add a custom DataType Attribute to the properties that RuleBox would use to establish what datatype to validate against.
  3. Expose SmartDate etc. private variables as SmartDate properties, and live with the limitations.
  4. Ask all of you for a better idea, because I really don't like any of the above.  #2 seems the lesser among evils.
Any other suggestions?


david.wendelken replied on Friday, August 03, 2007

Just thought up option #5, and might as well explore item #6:

5. Add a method to the business object that accepts a propertyName parameter and returns its datatype. 

6. Change SmartDate, etc. to a class.

The problem with options 1, 2,and 5 is that the programmer has to do extra work - and if they forget to do it - the RuleBox won't work as intended.  The whole idea behind setting up the RuleBox to automatically enforce standard rules on the client is to remove the need to code AND, more importantly, test that code.  I lose the "no need to test this, it just works!" beauty of the concept. :(

The problem with #6 is that everyone needs to agree to it or I've got a maverick installation of CSLA, and more to test with each upgrade.  Plus, it might break existing code. I don't fully understand the technical implications of changing from a struct to a class yet.  If it's just a matter of changing the word struct to class, and recompiling, and everything that used SmartDate works as before...

 

 

david.wendelken replied on Monday, August 06, 2007

RockfordLhotka:

No offense David, but this is really funny!!! Big Smile [:D]

SmartDate used to be a class, and I changed it to a value type in CSLA 2.0 because there was a lot of discussion by many people on the forum that pushed the change.

And they were right, btw, because DataTime is a value type, and SmartDate is trying to be as close to DateTime as possible while still providing its unique behaviors.

Ultimately though, Joe is right: SmartDate is designed to be used as a field, not a property, type. The idea is to expose a string property to allow the user to enter anything they want, and to use SmartDate behind the scenes to parse and process that input value.

I've searched the forums, but haven't found the discussions you mention.

 

JoeFallon1 replied on Monday, August 06, 2007

Did you search the *old* forums?

I just took a quick look and the Search mechanism for th eold forums no longer works.

The thread was started by Paul Tyng in 2004-2005 and discussed this topic.

Joe

 

RockfordLhotka replied on Monday, August 06, 2007

I think they were on the old forums.

 

While those forums are technically still available on msn, there’s no longer a search capability, so they could be hard to find, sorry.

 

Rocky

 

From: david.wendelken [mailto:cslanet@lhotka.net]
Sent: Monday, August 06, 2007 10:10 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Why is SmartDate a struct instead of a class?

 

RockfordLhotka:

No offense David, but this is really funny!!! Big Smile <img src=">

SmartDate used to be a class, and I changed it to a value type in CSLA 2.0 because there was a lot of discussion by many people on the forum that pushed the change.

And they were right, btw, because DataTime is a value type, and SmartDate is trying to be as close to DateTime as possible while still providing its unique behaviors.

Ultimately though, Joe is right: SmartDate is designed to be used as a field, not a property, type. The idea is to expose a string property to allow the user to enter anything they want, and to use SmartDate behind the scenes to parse and process that input value.

I've searched the forums, but haven't found the discussions you mention.

 



david.wendelken replied on Monday, August 06, 2007

Thanks anyway.  I tried googling it but got nothing useful. :(

One of my colleagues just got back from vacation, and immediately added option 7:

7.  Create a rule called DataType and pass in the datatype as an argument.  The rule doesn't actually have to do anything in the business object, i.e., it always returns true.  (Property setters are assumed to take care of datatype checking in the business object, at least the way we've been coding them.)

benefits:

  1. dirt simple to do.
  2. fits within the csla framework.  In pure rules theory, datatype restrictions are rules.
  3. easy to generate.

drawbacks:

  1. a bit of wasted processing once per object type.  (These aren't instance level rules, they are usually going to be object level rules.)  Of course, if it turns out to be useful, the datatype rule could actually be coded to check something.

 It's so easy to do this way, I was able to get my RuleBox class up and running.  It automagically recognizes the rules necessary to set up these validators to check for required fields, range of values, regular expressions, datatypes, and even sets the max field length. 

I suspect that accounts for 80% of the validators I would set up. (If I can get a compare validator setting up for other properties in the same record on the same page, I'll surely hit 80%!)

That means that when I code my business rules in my business objects, 80% of the rules will automagically get enforced on the client, with no effort on my part.  No client-side coding, no client-side testing, no client-side maintenance when those business rules change, nada! :)

happy, happy, joy, joy! Big Smile [:D]

 

Copyright (c) Marimer LLC