• LCrawford (unregistered)

    if frist.IsGreaterThen(else) {frist = true)

  • some guy (unregistered)

    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?

  • Jens (unregistered)

    For good reason the Timespan type does not have an "between" comparator. If they need this test, then something else is broken as well.

  • Prime Mover (unregistered)

    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.

  • (nodebb)

    No one here has heard of a Fluent Interface? This just looks like an amateur implementation of a generally accepted concept.

  • WTFGuy (unregistered)

    @Jens: Not sure I follow you.

    Timespan min = new Timespan(0, 0, 10); // 10 seconds
    Timespan max = new Timespan(0, 1, 0); // 1 minute = 60 seconds
    Timespan delay = WhateverFromUI() // get user input for desired delay
    if (delay.IsBetween(min, max) {
        // do whatever stuff using the validated delay value
    } else {
        // reject invalid input, ask again, etc.
    }
    

    Seems like a perfectly cromulent use case for a boundary check on a Timespan to me.

    What are you thinking about?

  • (nodebb)

    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???

  • Brian (unregistered) in reply to TheCPUWizard

    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.

  • Anonymous') OR 1=1; DROP TABLE wtf; -- (unregistered)

    IsBetweensOrEqual() with the plural betweens sounds like this is code written by a goblin.

  • WTFGuy (unregistered)

    @TheCPUWizard ref

    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...)

    That's a good start. But it's also

    Extension Methods for should-be Intrinsic operations on the class (things the class inherently could do if only the devs who wrote it had the foresight, skill, and budget to do a less half-assed job on the implementation)

  • Sole Purpose Of Visit (unregistered) in reply to WTFGuy

    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.)

  • WTFGuy (unregistered)

    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.

  • John (unregistered)

    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.

  • (nodebb)

    The logical operators lose the normal short-circuiting behavior.

  • (nodebb)

    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.

  • Dan Bugglin (google)

    On the bright side, they didn't add extensions to object (or else we'd be reading about that).

  • Sole Purpose Of Visit (unregistered) in reply to Loren Pechtel

    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 ...

  • Wizofaus (unregistered) in reply to Jens

    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".

  • Sole Purpose Of Visit (unregistered)

    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:

    1. Create your own "Decorator" class for TimeSpan
    2. That class will have an impl member for the actual TimeSpan
    3. The decorator will pass all but one methods through to the impl
    4. The single non-passthru method will be Equals
    5. The decorator will treat Equals as reference equality, not as value equality.

    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.

  • Sole Purpose Of Visit (unregistered) in reply to Sole Purpose Of Visit

    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:

    public int CompareTo (object obj);
    

    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.)

  • (nodebb)

    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.

  • (nodebb)

    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

  • markm (unregistered)

    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...

  • markm (unregistered) in reply to markm

    I forgot how this site eliminates single line breaks. Corrected:

    four versions:

    a < b < c; a <= b < c; a < b <= c; a <= b <= c

Leave a comment on “Extended Time”

Log In or post as a guest

Replying to comment #:

« Return to Article