Discussion:
Cannot dispose of mystery
(too old to reply)
Anton Shepelev
2017-09-28 09:57:46 UTC
Permalink
Hello, all

Can you please explain to me why the following code
doesn't compile in .NET 3.5:

ResourceReader rr;
rr = new ResourceReader( @"dummy.resources" );
rr.Dispose();

with error:

'ResourceReader' does not contain a definition for
'Dispose' and no extension method 'Dispose' ac-
cepting a first argument of type 'ResourceReader'
could be found (are you missing a using directive
or an assembly reference?)

whereas the following compiles and works:

ResourceReader rr;
IDisposable id;
rr = new ResourceReader(@"dummy.resources");
id = rr as IDisposable;
id.Dispose();
--
() ascii ribbon campaign - against html e-mail
/\ http://preview.tinyurl.com/qcy6mjc [archived]
Marcel Mueller
2017-09-28 21:05:56 UTC
Permalink
Post by Anton Shepelev
Can you please explain to me why the following code
Probably ResourceReader has only a private implementation of
IDisposable.Dispose.


Marcel
Arne Vajhøj
2017-09-29 01:16:35 UTC
Permalink
Post by Marcel Mueller
Can  you please explain to me why the following code
Probably ResourceReader has only a private implementation of
IDisposable.Dispose.
Shouldn't that give a compile error on ResourceReader if
its Dispose is not public?

Arne
Anton Shepelev
2017-09-29 09:29:25 UTC
Permalink
Probably ResourceReader has only a private imple-
mentation of IDisposable.Dispose().
This interface implementation syntax:

void IDisposable.Dispose()

is useful to avoid name collision when a class im-
plements several interfaces with identical methods
names. In this case the programmer must explicitly
cast the object to the desired interface. In the
case of ResourceReader.Dispose(), however, I see no
reason for this decision.
--
() ascii ribbon campaign - against html e-mail
/\ http://preview.tinyurl.com/qcy6mjc [archived]
Arne Vajhøj
2017-09-29 03:27:16 UTC
Permalink
Post by Anton Shepelev
Hello, all
Can you please explain to me why the following code
ResourceReader rr;
rr.Dispose();
'ResourceReader' does not contain a definition for
'Dispose' and no extension method 'Dispose' ac-
cepting a first argument of type 'ResourceReader'
could be found (are you missing a using directive
or an assembly reference?)
ResourceReader rr;
IDisposable id;
id = rr as IDisposable;
id.Dispose();
Some decompile reveals that 3.5/2.0 has:

void IDisposable.Dispose()
{
this.Dispose(true);
}
private unsafe void Dispose(bool disposing)
{

while 4.0 has:

public void Dispose()
{
this.Close();
}

[SecuritySafeCritical]
private unsafe void Dispose(bool disposing)

What can I say? WTF?

Arne
Anton Shepelev
2017-09-29 09:23:02 UTC
Permalink
Post by Arne Vajhøj
Can you please explain to me why the following
ResourceReader rr;
rr = new ResourceReader( "dummy.resources" );
rr.Dispose();
'ResourceReader' does not contain a definition
for 'Dispose' and no extension method 'Dispose'
accepting a first argument of type
'ResourceReader' could be found (are you missing
a using directive or an assembly reference?)
ResourceReader rr;
IDisposable id;
id = rr as IDisposable;
id.Dispose();
void IDisposable.Dispose()
{
this.Dispose(true);
}
private unsafe void Dispose(bool disposing)
{
public void Dispose()
{
this.Close();
}
[SecuritySafeCritical]
private unsafe void Dispose(bool disposing)
What can I say? WTF?
That explains it. Reference source has only the
latest version and I didn't think of decompiling.
Close() invokes Dispose( true ), but invoking
Close() from Dispose() is ugly because it is invert-
ed subordination. Dispose() is conceptually a low-
er-level method than Close().
--
() ascii ribbon campaign - against html e-mail
/\ http://preview.tinyurl.com/qcy6mjc [archived]
Anton Shepelev
2017-09-29 17:42:51 UTC
Permalink
For the sake of speed and simplicity, I want to
read an embedded resource from a .NET assembly file
without loading this assembly via reflexion.
I think the standard ResourceReader is defective.
Its constructor accepts the abstract Stream:

public ResourceReader(Stream stream)

and uses Stream.Seek() frequently without ever
checking whether the Stream.CanSeek():

http://referencesource.microsoft.com/#mscorlib/system/resources/resourcereader.cs,8590a202717adc1e

Don't you know where the code is that locates embed-
ded resources inside the file and passes them to
ResourceReader? I cannot seem to find it in the
Reference source.
--
() ascii ribbon campaign - against html e-mail
/\ http://preview.tinyurl.com/qcy6mjc [archived]
Arne Vajhøj
2017-09-30 18:25:19 UTC
Permalink
Post by Anton Shepelev
For the sake of speed and simplicity, I want to
read an embedded resource from a .NET assembly file
without loading this assembly via reflexion.
I think the standard ResourceReader is defective.
public ResourceReader(Stream stream)
and uses Stream.Seek() frequently without ever
Not nice.

But the documentation:

https://msdn.microsoft.com/en-us/library/9w9kac55(v=vs.110).aspx

says:

<quote>
Remarks

The ResourceReader(Stream) constructor instantiates a ResourceReader
object that retrieves resources either from a standalone .resources file
or from a .resources file that is embedded in an assembly. To read from
a standalone .resources file, instantiate a Stream object and pass it to
the ResourceReader(Stream) constructor. To read from an embedded
.resources file, call the Assembly.GetManifestResourceStream method with
the case-sensitive name of the .resources file, and pass the returned
Stream object to the ResourceReader(Stream) constructor.
</quote>

which hints at that the constructor is not intended to be
used with all kinds of streams.
Post by Anton Shepelev
Don't you know where the code is that locates embed-
ded resources inside the file and passes them to
ResourceReader? I cannot seem to find it in the
Reference source.
The Assembly.GetManifestResourceStream mentioned above??

Arne

Loading...