views:

127

answers:

3

Hello,

I must add some Dispose code to a class that inherits from a class that already implements IDisposable so I tried to do an Override of the Dispose method but I have not available the disposedValue because it is declared as private.

How can I add the new Dispose statements?

Protected Overridable Sub Dispose(ByVal disposing As Boolean)
    If Not disposedValue Then
        If disposing Then
           ''# ...
        End If
    End If
    disposedValue = True
End Sub

Thanks in advance!

EXTENDED INFO: I think that I should implement the same logic present at the base class at the inheritor. Am I right?

MORE INFO: I am using the snipet that Vb.Net automatically writes when you declare that a class implements IDisposable.

+2  A: 

You could make a separate disposedValue field in the derived class.
However, you should probably name it isDisposed.

Note that all classes in the FCL will not do anything if you call Dispose twice, so there isn't necessarily anything wrong with taking out that logic and disposing multiple times. Obviously, this depends on what you're doing in Dispose; you should check.

Make sure to call MyBase.Dispose(disposing).

SLaks
The real question is: why disposedValue is not declared as protected like the Dispose if the variable is needed to implement the override of the method?
SoMoS
And if I Dispose multiple times I can get a ObjectDisposedException because of the Dispose logic I have to implement.
SoMoS
`disposedValue` is private, because only the base class makes decisions based on it. Making it protected also enables setting it from the derived classes. If you set it in the derived class, and then call the base class, the base class will **not** dispose, and vice versa.
Sander Rijken
#1: Are you asking me why someone wrote some random class that I've never heard of and made a private field?
SLaks
#2: That's why I said that you should check. If the classes that you're using throw an `ObjectDisposedException` if they're disposed twice, they are wrong. (It says explicitly in http://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx, `If an object's Dispose method is called more than once, the object must ignore all calls after the first one. The object must not throw an exception if its Dispose method is called multiple times. Instance methods other than Dispose can throw an ObjectDisposedException when resources are already disposed.`)
SLaks
If they do throw `ObjectDisposedException`s in `Dispose`, then you will need to make your own `isDisposed` field in the derived class.
SLaks
Re 1#: I'm talking about the Dispose pattern that Visual Studio creates when you implement the IDisposable pattern (I suppose that this is the "official" Dispose pattern). ---Re 2#: I have to do something more before calling the Dispose method to Dispose the item. There is were the exception is thrown. Sander: I agree too. They should have created a private field with a readonly property.
SoMoS
ReRe #1: I don't know what you're referring to. ReRe #2: Then you'll need your own boolean field. Re: #3:Yes, they should have. For example, `Control` has a read only `IsDisposed` property. (Although `Component` unfortunately doesn't)
SLaks
ReReRe #1 (lol): in Vb.Net when you put that a class implements the IDisposable interface a IDisposable snippet is automatically written into your code. This snippet has the code that I wrote at the question plus the disposedValue as a private variable (and a few more things). That's why I expected that to be an official implementation. Now I see that I will have to rewrite it to put a readonly property.
SoMoS
A: 

Instead of trying to duplicate the base class logic, call MyBase.Dispose(disposing).

Eric Mickelsen
That won't tell him whether _his own_ objects have already been disposed.
SLaks
That's true. What I mean is, don't try to redo the base class disposal just because you don't have access to the disposedValue member. If there is additional disposal required for the derived portion of the object, do that as well, but, obviously, don't use the same disposedValue member to determine whether it should be done.
Eric Mickelsen
Well, more or less what SLaks said. The question is why I'm prevented of using disposedValue if this is just what anyone would need to do override the Dispose?
SoMoS
Well, you do want to call the base class dispose when you override. Therefore, setting disposedValue before the call would prevent proper disposal of the base, and setting it after would do nothing since it is already true. So, it does make some sense. You should just create your own member in the derived class.
Eric Mickelsen
A: 

Well, the fact that it is private instead of protected probably means you aren't supposed to do that. But if you insist, you could use reflection. Yeah, this is probably the worst possible way to do it:

//(System.Reflection.BindingFlags...)
this.GetType().GetField("_privateVarName", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this);
Brian
I agree. Then, how is expected someone to implement the override of the Dispose method? Of course I will not use reflection to do that.
SoMoS