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); } }
-
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{}
-
-
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
namedint
?
-
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"
-
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 aThreadAbortException
, 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
destroyingmaintaining: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?
-
Thank $deity I only have to maintain VB6 and not VB.NET
Hah, .NET is much easier...
Why are you messing about with Designer classes, though?
To remove the [expletive] that is pointless cruft.
-
@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.
-
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 "{"?
-
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
-
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.
-
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#)
-
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 yourSwitch
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.
-
If you have Case <> 6 in your Switch statement, I'm pretty sure you're Doing it Wrong™
QFT
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...
-
...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.
-
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.
-
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)
-
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
-
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.
-
...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.
-
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.
-
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.
-
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.
-
Which, frankly, is in general a better representation (at least in 2's complement).
Which I think is why they did it.
and True becomes -1.
Yeah, but I think there was another mso-style enumeration, is what I meant. It's not really important.
-
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)
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.
-
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.
-
Assignments are not expressions
In Basic maybe. In C-land (and those based from C) they can be (though, essentially always a True expression).
-
(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
-
In Basic maybe.
Yeah, it's almost as if we were talking about Visual Basic or something.
-
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.
-
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 tousing
, 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...
-
Maybe .NET could implement something similar in a later version, or at least I hope so...
Whoosh?
-
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"
-
Meh, just keep losing exceptions then when someone throws another from a
Dispose()
method.
-
Those will be sorted out by a GAU-8.