I have a struct which I want to add static methods to. Yes, you guessed right I'm talking about Datetime
.
It's a pretty typical requirement to add MyCustomParse. It happens to return Datetime?
, so it's not a constructor, but it's in that area, a static method that returns an instance. The content of this method has already been written and currently happy lives as a instance method of a class that uses it. I want to bring it out of that class so I can use it elsewhere.
Traditionally I would put it in a helper class (which is what I've done here), but apparently they're evil.
What I really want to do is tie Datetime.MyCustomParse(mystring)
. But the only way I can see is to make a new struct that composes Datetime
. I then add in my method, write the implicit conversions and then put in all the other Datetime
methods etc. This would be a pain to code (Being verbose also causes problems wrt xml docs and naive code coverage metrics, if that counts for anything).
I have considered extension methods, but I don't think the methods make sense on instances.
What is the strict OO position? Do I get a pass on writing methods that should belong to classes in separate helper classes when I want to extend structs in this fashion?
What is the pragmatic position (I'm not saying OO isn't pragmatic), is this code you would write, or have I missed a trick?
internal static class DateTimeHelper
{
public static DateTime? MyCustomParse(string utcDateTimeText, string[] formats)
{
DateTime utcDateTime;
if (DateTime.TryParseExact(utcDateTimeText, formats, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out utcDateTime))
{
return utcDateTime;
}
return null;
}
}
PS I know there are more nuanced views on helper classes, but I still feel I need to justify my use here.
Best Answer
"strict" is undefined in OO space?
OO Rationalization
Well, one approach may be to think about creational design patterns. I see this as counterpoint to the "helper class" idea. I see the "helper" as a smorgasbord - incoherent in terms of domain object design.
But a Factory, Builder, etc. composes behavior within an object- a domain-coherent thing. How is this different from a helper class? Intent.
OO Pragmatism meets Intent
Refactor to turn the method into a delegate. You can declare the delegate at the namespace level if necessary.
Write a instance-building something that registers/binds/whatever the delegate method. I expect the method's implementation will be inside this something.
Somthing's purpose in life is to instantiate fully-realized objects of the class/struct. Something does not contain those "random" type-specific (but not instance-owned) helper methods.
And because of intent we do not want the pragmatic approach of a class static method - which you have already dismissed.