Tuesday, March 13, 2007
« Issue with Orcas March 2007 CTP | Main | CSLA .NET 3.0 - WPF support progress »

String formatting in .NET is a pain. Not that it has ever been easy - even COBOL formatting masks can get out of hand, but there's no doubt that the .NET system is harder to grasp and remember than the VB 1-6 scheme...

I just had a need to format an arbitrary value using a user-supplied format string. You'd think that

obj.ToString(format)

would do the trick. Except that System.Object doesn't have that override of ToString(), so that's not a universal solution. So String.Format() is the obvious next choice, except that I need to somehow take a format string like 'N' or 'd' and make it into something valid for String.Format()...

Brad Abrams has some good info. But his problem/solution isn't quite what I needed. Close enough to extrapolate though:

outValue = string.Format(string.Format("{{0:{0}}}", format), value);

Given a format string of 'N', the inner Format() returns "{0:N}", which is then used by the outer Format() to format the actual value.


Wednesday, March 14, 2007 7:06:48 AM (Central Standard Time, UTC-06:00)
Good ole .NET. There's always more than 30 ways to get something done! How about this:

Convert.ToString(obj).ToString(format);

Wednesday, March 14, 2007 7:26:25 AM (Central Standard Time, UTC-06:00)
I'm not entirely sure that'd work, because by the time the actual format (like 'N') were applied, it would be applied to a value of type string, not int, double, DateTime or whatever. Then again, maybe .NET is smart enough to convert the string value back into one of those types to do the format. But if that happens, you'd have extra conversions going on, which could be less than ideal for performance.
Wednesday, March 14, 2007 8:03:31 AM (Central Standard Time, UTC-06:00)
Oh! Sorry about that. If you are formatting a number, then you'd have to use Convert.<ToInt32, ToDecimal, ToDateTime, etc.>. I'm sure it works.

And I'm sure there's no more conversion or performance issues than what you came up with.
Wednesday, March 14, 2007 8:48:40 AM (Central Standard Time, UTC-06:00)
In my case I don't know the type - it is generic - and so (without resorting to a huge switch statement) there's no way to do strongly-typed converts.
Wednesday, March 14, 2007 9:14:42 AM (Central Standard Time, UTC-06:00)
Hmmm. I'm not sure why you wouldn't know the type if you need it formatted a particular way. But I'm not questioning that that's not the case. I've been around long enough to know that you can't always know exactly what you're dealing with.
Wednesday, March 14, 2007 9:28:10 AM (Central Standard Time, UTC-06:00)
Csla.Validation.CommonRules.MaxValue<T> is a rule method that can validate any IComparable type. If the validation fails, the broken rule description includes the max value so the user can see the limit. That max value is of type T, constrained only by IComparable.

One feature request for CommonRules is to allow formatting of that value in the output, which seems like a very valid and useful idea. So the caller (the business object) needs to specify the format string it wants to use, but MaxValue has to do the actual formatting of something of type T.
Thursday, March 15, 2007 11:44:24 AM (Central Standard Time, UTC-06:00)
Would it make sense to check T to see if it implements IFormattable? If so, cast, then use .ToString(format, null). If the generic isn't IFormattable, then just .ToString()?
Richard Morgan
Comments are closed.