• ray10k (unregistered)

    Meh. Today's article was a lot of buildup to something that would otherwise just be one item in one of those "Look at these funny function names" articles.

  • Steve_The_Cynic (nodebb)

    Which tyranny that is Hungarian Notation?

    That is, "applications" or "systems" HN. Systems HN is a crime against humanity. (It is the origin of the w in wParam, "word Parameter" versus the l in lParam, "long Parameter", doubly distressing since wParam is no longer a WORD.)

    Applications HN says that the wart shows information about the variable that is not captured, as such, in its type. Example: cbFribble is a count of bytes somehow linked to fribbling. We know it's an unsigned type of some sort from its declaration, but the "cb" adds the information that it's a byte count.

    More ... enlightened ... languages than C can do this by having proper separation of types (XMLSanitizedString, HTMLEncodedString, UntrustedString, NonEncodedString), but that's the origin. Someone (else) at Microsoft got hold of this idea and mutated it into what we see now as Systems HN, where people say "int iNum" as if the "i" in "iNum" actually adds something (instead of encoding the "fact" that iNum is an int). And, worse, they end up with variables whose name is just the wart. How many programs contain declarations like "HWND hwnd;"?

  • poniponiponi (unregistered) in reply to Steve_The_Cynic

    To this day I always thought LPARAM meant "Left Parameter" and WPARAM meant "Some-Foreign-Word-Translating-To-'Right' Parameter".

    Anyway, I've no particular problem with hungarian notation, but a decade of interaction with insufferable Apple fanbois has given me an intense revulsion for anything prefixed with a superfluous "i".

  • Pig Dog (unregistered)

    No FristSuckingPigDogs today?

  • bvs23bkv33 (unregistered) in reply to poniponiponi

    LPARAM is long pointer to ARAM

  • The MFC Specialist (unregistered)

    HWND - handle to a Windows-Object - basically a pointer - That was a good mind-bendig abbreviation.

    But the best of all hungarian notations and most used one in the Microsoft Foundation Classes is: LPTCSTR

    Long pointer to a text-character c-style string. Text character means Unicode. And a C-string is 0-terminated and different from a B-string.

  • fristy (unregistered)

    That hurts my c-string

  • Chris (unregistered)
    Comment held for moderation.
  • Dan Bugglin (google)

    Actually, the extension method has one advantage over calling .Dispose() directly, in that it will also work on classes that implement IDisposable explicitly.

    Implementing an interface explicitly means the methods don't show up on the normal class, possibly because there are name conflicts that would arise if you did so, BUT you can cast to the interface type and then use the methods from there. This extension method allows you to do that in one step.

    But yeah if you have control over the class code, you can just code in a method directly that casts its own instance and calls .Dispose(). Extension methods are intended for classes you can't modify directly (eg sealed, closed source, etc).

    Also, "Finalize" is only a thing in VB.NET. In any other sane language (C#) it's called the destructor.

    Addendum 2017-02-01 07:52: [Edit: Actually, I'm not sure if the extension method would be callable without casting. I've never tried anything like this!]

  • Elmer Fudd (unregistered) in reply to poniponiponi

    To this day I always thought LPARAM meant "Left Parameter" and WPARAM meant "Some-Foreign-Word-Translating-To-'Right' Parameter".

    Actuawwy, dat's wight.

    (Yes, Googwe, I'm no wobot.)

  • Foo AKA Fooo (unregistered) in reply to bvs23bkv33

    Abstract RAM, the next step after virtual memory.

  • Ron Fox (google)

    TRWTF is calling C# .NET

  • Stephen Cleary (unregistered) in reply to Dan Bugglin

    While this is correct, it's sidestepping the point that you almost never should call Dispose directly. You should be using "using". The only common use case for this extension method that I can see is that it saves you a cast when implementing Dispose - and it does so at the cost of some obfuscation, not a good tradeoff IMO.

    "Finalize" is only a thing in VB.NET. In any other sane language (C#) it's called the destructor.

    Except C++. Where "destructor" is already a thing. So "destructor" means "Dispose". :/

  • That's Mr. Pedantic, to you (unregistered)

    Hate to be the pedant of the bunch, but nobody else has mentioned it yet:

    You can't declare extension methods in any class... You can only declare them in a public/internal static class.

  • Amac (unregistered) in reply to Chris

    SHITEMID stands for Shell Item ID. Explorer is essentially the shell UI. And Windows Explorer is as well, but with a specific purpose.

    An SHITEMID could represent a file, a directory, or one of the "virtual" directories: Desktop, My Documents, etc. It was while working with the shell that I came to the conclusion that's why Windows started referring to directories as folders.

    A directory is a "physical" location, but a folder doesn't have that limitation. The directory it represents can be different. A good example of this would be the Desktop folder. There's a specific SHITEMID for it, but the physical location is different depending on who's logged in.

  • Russell Judge (google)

    Damn, this soapbox is getting dirty. I think I'll Dispose of it.

  • Amac (unregistered) in reply to Stephen Cleary

    "almost never should call Dispose directly. You should be using "using""

    There are plenty of times you need to call Dispose directly, which is basically when using "using" does fit. One obvious situation you have to call Dispose would be when you're implementing it: you need to call Dispose() of any data members.

    or if the disposable object is returned from a method. The disposable object gets created and before being returned some further work is done, which could result in a exception being thrown. In the catch block, you would need to call Dispose()

    "Except C++. Where "destructor" is already a thing. So "destructor" means "Dispose""

    Good ol' C++. I miss C++ destructors. The closest thing you can get in .NET is a try/finally. Anyway, a C# destructor does not mean Dispose(). C#'s destructor is how you define an object's finalizer. It's the equivalent of VB.NET's Finalize(). Dipose() is meant to cleanup/release managed resources, which helps making objects available for garbage collection sooner. The finalizer gets called by the garbage collector after collection and is meant to cleanup/release unmanaged resources.

    Best practice for implementing Dipose() is that if your object doesn't use any unmanaged resources, you tell the GC not to bother calling the finalizer via GC.SuppressFInalize()

  • Mason Wheeler (unregistered) in reply to Amac

    The way I do it is, Dispose cleans up all resources, managed and unmanaged, and calls GC.SuppressFInalize(). The destructor throws, because if it's getting called, that means you forgot to call Dispose somewhere, which is a bug, so you need to call attention to it and fix it.

  • The_Dark_Lord (nodebb)

    .NET is a language?

  • Paul Neumann (unregistered) in reply to The_Dark_Lord

    Yep. And so is 'murican.

  • Guy (unregistered)
    Comment held for moderation.
  • powerlord (nodebb)

    The I makes sense in a way. You can tell at a glance if an inherited symbol is a class (limit 1) or an interface (unlimited).

    Java took a different route by using different inheritance keywords for classes (extends) and interfaces (implements).

    It also helps in cases where an implementation and interface would otherwise have identical names (i.e. IList<T> and List<T>).

    Addendum 2017-02-01 10:49: Gotta love how the edit button doesn't let me modify what was already in my post to fix the comment parser not like less-than signs.

  • Vilx- (unregistered)

    That said, implementing an interface method privately seems like an anti-pattern.

    There are use-cases for that still. Consider:

    interface ICloneable { object Clone(); }
    class Stormtrooper: ICloneable {
        public Stormtrooper Clone() { /* Kamino magic */ }
        ICloneable.Clone() { return this.Clone(); }
    }
    
  • darkestkhan (unregistered) in reply to Dan Bugglin

    Finalize is also a thing in Ada. It is procedure that performs finalization on object of given type. Also: Object is an entity of given type. Although in other languages you call that destructor. Dunno what objects are in other languages.

  • Jeremy Hannon (google) in reply to Ron Fox

    The concepts talked about apply to most .Net languages. IDisposible is part of the framework and, therefore, applicable to all .Net languages. I believe the extension methods are fairly common as well, though I do believe it is language dependent. VB.Net and C# both implement the extension method concept, and can use extension methods from .Net libraries built in other .Net languages.

    So, while the examples are C#, everything is applicable to most .Net languages... though I have little experience with IronPython, F#, Cobol.Net, etc.

  • Tim! (unregistered) in reply to That's Mr. Pedantic, to you

    What are you pedanting about exactly? I don't see anyone claiming that you can declare extension methods in any class.

    You can declare extension methods of any class.

  • Tim! (unregistered) in reply to Steve_The_Cynic
    Comment held for moderation.
  • Scott Christian Simmons (google)

    It's possible this is a relic of a wrestling match Kaleb's co-worker had at some point in the past with the .NET framework's numerous garbage collection bugs in versions 1.0 and 1.1.

    If so, the sad part is that it was left in because he went on to try other fixes after it didn't help.

  • Zenith (unregistered) in reply to The MFC Specialist

    Actually, the T is platform specific. The default is ANSI, W is for Wide/Unicode.

  • Simon (unregistered)

    Not familiar enough with C#, but I gather IDisposable is essentially the same concept as Closable / Autoclosable in Java? Essentially, it signifies that the class holds onto resources that need to be cleaned up - allowing it to participate in language features for cleaning up on scope exit (instead of GC), and allowing for tools like IDEs to help spot resource leaks?

  • strLicoriceAnyone (unregistered) in reply to Chris

    Spunk? Also a Danish licorice...

  • foxyshadis (unregistered) in reply to powerlord

    Of course, in Java every damned class is a AbstractSomething or SomethingImpl anyway. Why do Java people love Impl so much, when the standard library never once uses it? Who knows.

  • snoofle (unregistered) in reply to foxyshadis

    Because they tend to shy away from the "I" prefix for interfaces, so you have Widget (interface) and WidgetImpl (class). Personally, I prefer IXxx and Xxx, but that's just me.

  • Ingo B. (unregistered) in reply to Steve_The_Cynic

    Actually "HWND hwnd" isn't the best example of using just the wart. The best one is "int i", if you think about it.

  • Pig Dog of the Cat Universe (unregistered)

    Woof.

  • Watchman (unregistered)

    This code looks fine to me. It actually looks even better than just calling .Dispose(), because it indicates to future maintainers that there's some issue with the object or the disposal of the object - it's a big "tread cautiously" sign. At worst, it's something that puts a smile on someone's face, with no adverse consequences.

    I guess the submitter has a stick up their butt about Enterprise Code Standards or the like? I'm all in favour of removing pointless obfuscations that add nothing, or removing complicated workarounds. I see nothing wrong with this, though.

  • Greg (unregistered) in reply to The MFC Specialist

    Almost but not entirely right (you forgot the C means const):

    LPCTSTR = Long Pointer to a Const TCHAR STRing

  • Bert (unregistered)

    If you implement Dispose privately, that means you're {re,ab}using the built-in interface for something other than the one thing it's supposed to be used for. So make another interface and use that.

  • Medinoc (nodebb) in reply to Greg

    Plus, that part is not the "Systems Hungarian Notation" part. The "Systems Hungarian Notation" part is when this type is later used to declare a LPCTSTR lpszString;

  • Brian (unregistered) in reply to The MFC Specialist

    "But the best of all hungarian notations and most used one in the Microsoft Foundation Classes is: LPTCSTR

    Long pointer to a text-character c-style string. Text character means Unicode. And a C-string is 0-terminated and different from a B-string."

    Almost. the 'T' stands for TCHAR, which is a Microsoft abomination whose type depends on a preprocessor definition. If UNICODE is defined, it evaluates to wchar_t; otherwise it's a plain old char. Better hope all your objects are compiled the same way...

  • Jim (unregistered)
    Comment held for moderation.
  • Brian the Superninja (unregistered) in reply to Mason Wheeler

    Your comment is the first genuinely insightful thing I've read on this thread. Makes total sense. Put a throw in the finalizer and that way you know when dispose hasn't been called. Might save ages messing about with the memory profiler to find leaks.

  • Jeff Dege (unregistered)

    Years ago I wrote a rant on Hungarian notation. If you read Simonyi's thesis, his idea makes perfect sense in languages like C that have limited capability for defining new types.

    What Microsoft did makes no sense at all, and clearly demonstrates that whoever came up with the implementation flat-out didn't understand what Simonyi was talking about.

    Simonyi advocated for prefixes that represent the logical type of a variable. So ints containing colors and ints containing automobile models and ints containing dog species would have different prefixes. MS decided, in it's wisdom, to define prefixes for the physical representation of a variable, so colors and automobile models and dog species would all be prefixed with "i". Not only is this pointless, it's encoding in the name precisely what you don't want to be encoding in the name.

    http://forums.devx.com/showthread.php?2179-Hungarian-naming-convention

  • Geek (unregistered)

    Has no one else noticed that the theory that LParam stands for left parameter fails immediately due to the fact that lParam is the rightmost parameter?

  • smf (unregistered) in reply to Stephen Cleary

    "using" only works if you have a linear execution path.

    If your class leaves a file open so that future method calls can access it then you're going to end up implementing and calling dispose (although on a file, you'd normally call close).

  • Kaleb (unregistered) in reply to Watchman

    LOL! Um, if I were as you described, I would be removing the "offending" code, not submitting it to a website for laughs. ;-)

Leave a comment on “Someone Hates These Interfaces”

Log In or post as a guest

Replying to comment #:

« Return to Article