How to increase your LOC count with IDisposable



  • Discovered while investigating "A generic GDI+ exception occurred" and other werid memory related issues. Can anyone figure out why this code would be written? To me it looks like someone was bent on either increasing their number of lines committed or on preventing the Library from properly cleaning up of all resources in this class and its derivations.

    public class MyImplementation : SomeLibraryClass
    {
      // some vars
      ~MyImplementation() { this.Dispose(); }
    
      new public void Dispose()
      {
        base.Dispose();
      }
    
      new public void Dispose(bool disposing)
      {
        base.Dispose(disposing);
      }
    }

  • Discourse touched me in a no-no place

    That's a pretty half-assed implementation of IDispose. Maybe the class doesn't actually have anything to dispose of?



  • "I don't understand finalizers, I don't understand IDisopsable...so if I mash them together I get a FinalGarbageDisposal...so all is well? Eff-it. It compiles, ship it."



  • Pseudo-Go code for the same result:

    type MyImplementation struct {
        some.LibaryClass
        int count
    }
    
    // Verify that it satisfies the contract
    var _ io.Disposable = &MyImplementation{}
    

  • Discourse touched me in a no-no place

    @riking said:

    Pseudo-Go code for the same result:

    Away with you, ben_lubar sockpuppet!



  • Pseudo-C# code for the same result:

    // there is also no code required for inherited method implementations in C#
    


  • Also, why do you have a value of type count named int?



  • Something to add to make it different from the original type, I suppose.



  • TRWTF is classes that violate the Microsoft specification by throwing exceptions from within the Dispose method.
    Including Microsoft's own devs, who created Windows Communication Foundation. I have a voodoo doll full of pins for these guys. All pins labeled "CommunicationObjectFaultedException"



  • @Medinoc said:

    TRWTF is classes that violate the Microsoft specification by throwing exceptions from within the Dispose method.
    Including Microsoft's own devs, who created Windows Communication Foundation. I have a voodoo doll full of pins for these guys. All pins labeled "CommunicationObjectFaultedException"

    "Throwing exceptions from within the Dispose method" sounds suspiciously like the reason why you never throw exceptions in C++ destructors. If my class has a throwing destructor that is called while a thrown exception is unwinding the stack (looking for a catch clause for the exception), and I actually throw in the call to my destructor, that's it, game over, the fat lady is singing, etc. The C++ exception handling system will call terminate(); and calling terminate(); is more or less equivalent to calling abort().



  • .Net is more forgiving, though I'm not sure it's actually a bad thing: The new exception simply replaces the current one.
    It's possible (though I haven't tested) that it may even override a ThreadAbortException, which would be a WTF itself.

    The typical "use case" where you encounter exceptions thrown from Dispose is WCF:

    try   
    {
        using(myWcfChannel = CreateMyWcfChannel())
        {
            DoStuff(myWcfChannel); //Let's assume the remote method fails for any reason
        } //Congratulations! Your exception is now a CommunicationObjectFaultedException!
    }
    catch(SomeException ex)
    {
        LogException(ex);
        DisplaySomeErrorMessage();
    }
    

    I don't understand how they could ever think it was a good idea. I know the communication object is faulted, you morons! Why do you think I'm disposing of it?



  • Clean as hell compared to the code that I'm destroying maintaining:

    Namespace DataClass
        Public Class AnonymizedRecord
            Inherits Component
            Private pDisposed As Boolean = False
            Private sErrorMessage As String = String.Empty
    
    #Region " Component Designer generated code "
            Public Overloads Sub Dispose()
                If pDisposed = False Then
                    Try
                        MyBase.Dispose()
                        GC.SuppressFinalize(Me)
                        pDisposed = True
                    Catch ev As Exception
                    End Try
                End If
            End Sub
            Public Sub New(ByVal Container As System.ComponentModel.IContainer)
                MyClass.New()
                'Required for Windows.Forms Class Composition Designer support
                Container.Add(Me)
            End Sub
    
            Public Sub New()
                MyBase.New()
                'This call is required by the Component Designer.
                InitializeComponent()
                'Add any initialization after the InitializeComponent() call
            End Sub
            Public ReadOnly Property ErrorMessage() As String
                Get
                    Return sErrorMessage
                End Get
            End Property
    
            'Component overrides dispose to clean up the component list.
            Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
                If disposing Then
                    If Not (components Is Nothing) Then
                        components.Dispose()
                    End If
                End If
                MyBase.Dispose(disposing)
            End Sub
    
            'Required by the Component Designer
            Private components As System.ComponentModel.IContainer
    
            'NOTE: The following procedure is required by the Component Designer
            'It can be modified using the Component Designer.
            'Do not modify it using the code editor.
            <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
                components = New System.ComponentModel.Container
            End Sub
    #End Region
    
    ' Other class stuff
    
    End Namespace
    


  • Thank $deity I only have to maintain VB6 and not VB.NET



  • Why are you messing about with Designer classes, though?



  • @Spencer said:

    Thank $deity I only have to maintain VB6 and not VB.NET

    Hah, .NET is much easier...

    @BC_Programmer said:

    Why are you messing about with Designer classes, though?

    To remove the [expletive] that is pointless cruft.



  • @chubertdev said:

    @Spencer said:
    Thank $deity I only have to maintain VB6 and not VB.NET

    Hah, .NET is much easier...

    I guess there will be some things made easier by the better Intellisense found in VS. I'll take your word for it for the rest, I'm sticking with C# and F# in .NETland if I can help it.


  • Discourse touched me in a no-no place

    @Spencer said:

    I guess there will be some things made easier by the better Intellisense found in VS. I'll take your word for it for the rest, I'm sticking with C# and F# in .NETland if I can help it.

    Geez, how many times do you have to be told that VB.Net is basically C# with "begin" instead of "{"?



  • @FrostCat said:

    Geez, how many times do you have to be told that VB.Net is basically C# with "begin" instead of "{"?

    Well, seeing as this is the first... I'm going to go with another 11 more times.
    One of the main things that really annoys me is the predisposition for Hungarian notation with anything written in VB.

    I'm also going to leave this here



  • @Spencer said:

    One of the main things that really annoys me is the predisposition for Hungarian notation with anything written in VB.

    So you hate a language because of something that has nothing to do with the language itself.



  • @chubertdev said:

    So you hate a language because of something that has nothing to do with the language itself.

    I avoid things written in the language because of a style people who use the language are more likely to use.



  • Hating something cause of Hungarian notation is also wrong. Apps Hungarian is awesome.



  • It's one reason, not the sole one.
    There are more reasons I don't like VB, which combined lead to a general dislike of the language (enough of a dislike that when considering starting a new project, VB is only considered if there is some legacy reason for it, in which case it necessitates VB6... if it can be .NET it may as well be C#)


  • Discourse touched me in a no-no place

    @Spencer said:

    Well, seeing as this is the first

    Was it? NM then--I know it's been brought up, but maybe not in topics you've read.

    Regarding your wikiquote, that essentially agrees with me. "The bulk of the differences ... are syntactic sugar." begin/end vs {} may not be that, but it's not a meaningful difference.



  • It was more a link to the article, which lists features not found in either.

    Some examples:

    • Inline date declarations, using #1/1/2000# syntax (M/dd/yyyy)
    • I'm gonna go grab my cluebat now, for whoever decided to force that format string on everyone
    • Case statements may contain inequality expressions
    • If you have Case <> 6 in your Switch statement, I'm pretty sure you're Doing it Wrong™
    • Conversion of Boolean value True to Integer may yield -1 or 1 depending on the conversion used
    • Assigning and comparing variables uses the same token: =. Whereas C# has separate tokens, == for comparison and = to assign a value
    • When assigning a value to a variable with a different data type, VB.NET will coerce the value if possible.

    I'm also going to take my cluebat to which ever DiscoDev decided it was a good idea that, when hitting Shift+Enter in the textbox to create a new item in your unordered list, it should go back and undo any extra indentations (for sub-points) you've made.



  • @Spencer said:

    If you have Case <> 6 in your Switch statement, I'm pretty sure you're Doing it Wrong™

    QFT

    @Spencer said:

    Conversion of Boolean value True to Integer may yield -1 or 1 depending on the conversion used

    ...WTF? This sort of crud makes me wonder why people don't just code in a sane language, such as Python...



  • @tarunik said:

    ...WTF? This sort of crud makes me wonder why people don't just code in a sane language, such as Python...

    Same here. That's not a case of the language doing something wrong, so much as why it even allows it, though.

    So how did we get on the VB / C# debate in .NET?

    My main point of contention was that someone said that they prefer VB6 to VB .NET, which is the original statement that I thought was idiotic.


  • Discourse touched me in a no-no place

    @Spencer said:

    It was more a link to the article, which lists features not found in either.

    Right, but again, you're not disproving "mostly the same." That's all I'm saying. VB.Net is far more like C# than it is like VB6. If you still don't want to use it, that's fine, but don't refuse to use it just because you don't like old VB.


  • Discourse touched me in a no-no place

    @tarunik said:

    Conversion of Boolean value True to Integer may yield -1 or 1 depending on the conversion used

    ...WTF? This sort of crud makes me wonder why people don't just code in a sane language, such as Python...

    I bet that's got something to do with the fact that old-school VB True was -1, not 1 (IIRC). There's probably some legacy conversion. Would be nice if Wikipedia had given examples (or maybe it did and Spencer just didn't show 'em)



  • @FrostCat said:

    I bet that's got something to do with the fact that old-school VB True was -1, not 1 (IIRC). There's probably some legacy conversion. Would be nice if Wikipedia had given examples (or maybe it did and Spencer just didn't show 'em)

    Paging MsoTriState


  • Discourse touched me in a no-no place

    @chubertdev said:

    Paging MsoTriState

    ...which has true, false, and three unsupported options, so it's really a pentastate. Unless you wanna get meta, in which case I'll get even more meta and suggest the three unsupported ones aren't the same, because they have different names.



  • @FrostCat said:

    ...which has true, false, and three unsupported options, so it's really a pentastate. Unless you wanna get meta, in which case I'll get even more meta and suggest the three unsupported ones aren't the same, because they have different names.

    Hmmm, going off of memory, I thought that MsoTrue was -1, but MSDN says otherwise. Hence why I referenced it.


  • Discourse touched me in a no-no place

    @chubertdev said:

    Hmmm, going off of memory, I thought that MsoTrue was -1, but MSDN says otherwise. Hence why I referenced it.

    I thought the same too--you were probalby thinking of a different enum, because I think there used to be one that had "True" and "VBTrue" or something.



  • @FrostCat said:

    I thought the same too--you were probalby thinking of a different enum, because I think there used to be one that had "True" and "VBTrue" or something.

    and **True** becomes -1.


  • @FrostCat said:

    I bet that's got something to do with the fact that old-school VB True was -1, not 1 (IIRC).

    Which, frankly, is in general a better representation (at least in 2's complement).



  • Inline Date declarations come from VB2+ Date Literals. Why they bothered to keep anything when they removed all the other idiotic language crap, I'm not sure.

    Would be funny if the specific date literal format actually depended on the locale of the system being used to compile it.

    Select Case has generally been more powerful than switch. eg Case 1 to 4, 6 to 12, y to z would be a valid case; Case "Apples" to "Fruit", Case Is < 5, 34 would be valid too, and so on.

    Boolean conversions would depend on the conversion used. Old functions will return -1 to be consistent with VB6 and earlier. new functions/methods will return 1 because they are .NET Functions and don't give a shit about being compatible with VB6 at any level. -1 as true comes from BASIC which used it because there was literally no Boolean. you would define FALSE as 0 and then define TRUE as Not FALSE, which would perform a bitwise not and it would be -1. So when VB itself added constants they adopted the in-place convention that was already being used.

    Assignments are not expressions so using the same token isn't typically a problem. (Unless they changed it, if assignments work as expressions than that get's weird fast)

    Coercion crap has been in VB since VB2. I think the real issues with VB.NET is that they changed it enough from VB6 for VB6 developers to crusade against the new version, but still kept these rather silly vestigials.

    Given the choice I would rather deal with VB.NET over VB6. Even opening some of my old projects apparently crashes the IDE. Good times.


  • Discourse touched me in a no-no place

    @Maciejasjmj said:

    Which, frankly, is in general a better representation (at least in 2's complement).

    Which I think is why they did it.

    @chubertdev said:

    and True becomes -1.

    Yeah, but I think there was another mso-style enumeration, is what I meant. It's not really important.



  • @BC_Programmer said:

    Would be funny if the specific date literal format actually depended on the locale of the system being used to compile it.

    Yeah, I rather do like the big endian constructors

    New Date(2000, 1, 1)

    @BC_Programmer said:

    Select Case has generally been more powerful than switch. eg Case 1 to 4, 6 to 12, y to z would be a valid case; Case "Apples" to "Fruit", Case Is < 5, 34 would be valid too, and so on.

    I love that syntax. Although I wouldn't say it's more powerful overall, it does have features that switch doesn't. I'd like to see both constructs in both languages.



  • @FrostCat said:

    Yeah, but I think there was another mso-style enumeration, is what I meant. It's not really important.

    I was looking for one, but couldn't find any.



  • @BC_Programmer said:

    Assignments are not expressions

    In Basic maybe. In C-land (and those based from C) they can be (though, essentially always a True expression).



  • @Spencer said:

    (though, essentially always a True expression).

    Wrong; they evaluate to whatever was assigned to the LHS - so it can be false.



  • Oh yeah, you're right. Same principle to doing x = y = a



  • @Spencer said:

    In Basic maybe.

    Yeah, it's almost as if we were talking about Visual Basic or something.



  • @BC_Programmer said:

    Visual Basic or something

    VB features (or missing features) compared to other languages (primarily, C#).
    Pointing out that assignments aren't expressions in VB is pointing out another reason why I prefer not to use it.



  • Dealing w/ VB.NET - open project in VS, Ctrl + Shift + B, open binary in ILSpy or other .NET reflector of your choice, select C#, File -> Save Code

    Problem solved.

    Dealing w/ VB6 - find tall building, throw PC containing program from roof

    Problem solved.


  • Fake News

    @Medinoc said:

    using(myWcfChannel = CreateMyWcfChannel())
    {
    DoStuff(myWcfChannel); //Let's assume the remote method fails for any reason
    } //Congratulations! Your exception is now a CommunicationObjectFaultedException!

    When Java 7 finally implemented something similar to using, the designers had the sense to store the "suppressed" exceptions in the new exception. Maybe .NET could implement something similar in a later version, or at least I hope so...



  • @JBert said:

    Maybe .NET could implement something similar in a later version, or at least I hope so...
    Whoosh?


  • Fake News

    I don't know my way around .Net, but that seems more similar to the cause field in Java. I'm talking about suppressed exceptions, not about rethrown or wrapped exceptions.

    EDIT: This reminds me how Sun was royally late in adding that cause field, only in Java 1.4 did they notice that reinventing the wheel in hundreds of derived exceptions might not be a good idea.



  • Hopefuly, .NET would never implement an idea that sounds as stupid as "suppressed exceptions"


  • Fake News

    Meh, just keep losing exceptions then when someone throws another from a Dispose() method.



  • Those will be sorted out by a GAU-8.


Log in to reply