- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
if frist.IsGreaterThen(else) {frist = true)
Admin
For me, the parameter names on IsBetweensOrEqual (which is strange grammar at the very least) take the cake, because there is zero indication whether b >= c or b <= c. Yes, convention-based, one expects the smaller to be up front, but would a better name have killed here?
Admin
For good reason the Timespan type does not have an "between" comparator. If they need this test, then something else is broken as well.
Admin
People who use "then" for "than" need to be kicked up the ar$e around the world, and kicked around the world again for good measure.
Admin
No one here has heard of a Fluent Interface? This just looks like an amateur implementation of a generally accepted concept.
Admin
@Jens: Not sure I follow you.
Seems like a perfectly cromulent use case for a boundary check on a Timespan to me.
What are you thinking about?
Admin
Class Methods for Intrinsic operations on the class (things the class inherently DOES).
Extension Methods for Extrinsic operations on the class (things that can be done TO an instance of the class...)
Also, for Fluent styles, the RETURN type is something that you are going to chain off of (such as a filtered set), tell me: what will you chain off of a boolean???
Admin
Obviously, you'd use .Equals() - as in "if (a.IsLessThen(b).Equals(FILE_NOT_FOUND) ... "
Joking aside, my company uses nUnit extensively, and their recommended approach looks very similar to this sort of syntax: Assert.That(foo, Is.EqualTo(bar)) and so forth.
Admin
IsBetweensOrEqual()
with the plural betweens sounds like this is code written by a goblin.Admin
@TheCPUWizard ref
That's a good start. But it's also
Admin
Well, more often, it's because you're dealing with a third-party object (quite possibly an interface), and you want to add extrinsic operations to it that happen to be necessary for your own environment. (I've implemented a half-assed Maybe monad in precisely this way.) Monkey-patching works for all manner of monkeys.
As a one-off "encapsulation" of code that might as well be written inline, however, as here ... it's an abomination.
(Not as bad as one version I saw in our code base, for which the "this" parameter was of type object. That's probably an extreme example of spanking the monkey, but it does demonstrate that extension methods, as with any "library mechanism," require a great deal of care.)
Admin
Just to be clear, I'm not defending the code in the article. It's WTFery. The comparisons and logicals add nothing to the language while the IsBetween is at least conceptually useful. But if needed exactly once in a codebase, properly belongs as inline code. For sure not every potentially reusable idea belongs in that giant ragbag Utilities class we all know is lurking somewhere in most codebases.
I was trying to understand what Jens' categorical rejection of Timespan.IsBetween() was about and point out to CPUWizard that his rubric is fine in concept and everybody should always follow it. But as you, SPoV, rightly say, often you're extending code you don't control. That has certainly been my primary use case for C# extension methods: an extrinsic implementation of what should have been intrinsic behavior.
Admin
You also have to remember that C# extension methods are just static methods that take the instance (if there is one) as the first parameter. This means that calling extension methods on a null reference is legal because it's not really trying to call an instance method under the hood. It's just calling a static method and passing a null reference as the first parameter. In other words, this is perfectly legal:
((string)null).SomeStringExtensionMethod();
This also means that the IsLessThen, IsGreaterThan and IsBetweensOrEqual can each throw a NullReferenceException because they do things like a.CompareTo without checking whether a is null.
Admin
The logical operators lose the normal short-circuiting behavior.
Admin
Other than the poor spelling I have no problems with IsLessThan/IsGreaterThan.
I do have a problem with IsBetweensOrEqual, though, that name is an abomination! It should be InRange. And, yes, there is a legitimate use for it on a TimeSpan--sanity-checking data.
And/Or should just be taken out and shot. Any programmer worth their salt these days will understand C-style logical operators.
Admin
On the bright side, they didn't add extensions to object (or else we'd be reading about that).
Admin
Well, you say that. (I think you might be overestimating the basic mathematical competence of programmers these days.)
However, you might want to look up Eric Lippert on "Hundred Year Mistakes." Turns out C operators aren't quite as obvious as you might think ...
Admin
It's not that hard to think of a scenario where we need to know if the length of a period of time is within a certain range (though admittedly for most cases you'd normally only care if it were above or below a given limit). But e.g., 0-5 seconds might be shown to the user as "fast", 5-10 seconds as "medium" and 10+ as "slow".
Admin
And I realise that Remy is (correctly) hedging the OP's pet idiot potential cargo-culting of "Functional Programming," but let's be honest, it doesn't really apply here.
The original operators are perfectly cromulent cases of "functional programming." It would be trivial to convert them to OCamL, F, Haskell, or any other functional programming language you wish.
The "IsBetweensOrEqual" "operator", in FP terms, is, I think, simply a concatenation or a comprehension or something or other. It's no more functional than the operators it comprehends. In no cases are side-effects relevant. (What with everything operating on native types, rather than, say, Properties.)
What is interesting, on the assumption that the idiot in question sees the need to replace the logical or operator, and the logical and operator, with And and Or -- to no purpose whatsoever -- is that the idiot in question didn't see to consider overriding Equals. (Or preferably replacing it with HonestGuvIWantValueEqualsNotReferenceEquals.
I see this as a sad reflection on the state of Wooden Table Programming these days. I mean, how can you possibly assume that Equals will always work the way you assume (by value) on a library-supplied class like TimeSpan? To break this, all you have to do is:
Well, bang goes that bit of "functional, but not, programming," doesn't it? TimeSpan is a struct, so you can't sub-class it. But you can certainly encapsulate it.
And, considering that TimeSpan already implements IComparable, you might as well replace the "where" clause by just requiring T to be TimeSpan.
Admin
Which makes the idiocy even more transparent.
Still, at least it's not based upon object, as I say. OTOH it could apply to absolutely any other IComparable you want it to. And there's only one method in the interface:
The fact that the target is of type object should be a bit of a giveaway as to how dangerous this might be.
I seem to be overthinking this. Sorry. tl;dr. (Bottom-posted.)
Admin
Bashing Extension Methods, Yeah!
You ever seen object-methods disappear when you forgot to install some magic library? Even Visual Studio goofs up and suggest wrong packages and references when it can't find said code.
Hate them with a passion, please.
Admin
Bashing Extension Methods, Yeah!
You ever seen object-methods disappear when you forgot to install some magic library? Even Visual Studio goofs up and suggest wrong packages and references when it can't find said code.
Hate them with a passion, please.
Addendum 2020-10-20 18:28: Oops; Doubly-clicked
Admin
I think the reason "between" methods are rare in libraries is that in general you will need four versions:
a < b < c a <= b < c a < b <= c a <= b <= c
If you do create these, then you have to name them. You either have names that are so cryptic the programmers often mix them up (inserting bugs), or so long no one can type them without using autocomplete - and often accept the wrong one (inserting bugs). (For normal programmers, that is; someone who confuses "then" and "than" seems likely to have about a 25% chance of picking the right one out of four.) So for anyone that is really comfortable with c-like languages, it's easier to use the comparison and && operators and know what you are getting.
OTOH, I suspect the original programmer here learned to program in some quite different language and could not remember the c operators. Therefore, he hid them in misspelled methods...
Admin
I forgot how this site eliminates single line breaks. Corrected:
four versions:
a < b < c; a <= b < c; a < b <= c; a <= b <= c