Saw this. Why the explicit cast to IDisposable? Is this just a shorthand to ensure that IDisposable is called on exiting the using block?
using (proxy as IDisposable)
{
string s = prox开发者_开发知识库y.Stuff()
}
This "trick", if you can call it that, is most likely due to proxy
being of a type that the compiler can't verify really implements IDisposable
.
The nice thing about the using
directive, is that if the parameter to it is null
, then no call to Dispose
will be done upon exiting the scope of the using
statement.
So the code you've shown is actually short-hand for:
var disposable = proxy as IDisposable;
try
{
string s = proxy.Stuff();
}
finally
{
if (disposable != null)
disposable.Dispose();
}
In other words, it says "if this object implements IDisposable, I need to dispose of it when I'm done with the following piece of code."
This could be required if you are given a proxy
instance from somewhere and its static type does not implement IDisposable
but you know that the real type may do and you want to make sure it will be disposed e.g.
public class Proxy : ISomeInterface, IDisposable
{
...
}
private ISomeInterface Create() { ... }
ISomeInterface proxy = Create();
//won't compile without `as`
using(proxy as IDisposable)
{
...
}
It's unnecessary as the using
statement is explicitly tied to the IDisposable
interface, per the MSDN docs
Provides a convenient syntax that ensures the correct use of IDisposable objects.
edit: The C# language spec (sec. 8.13) provides three possible expansions for the using
statement's syntactic sugar:
A using statement of the form
using (ResourceType resource = expression) statement
corresponds to one of three possible expansions. When ResourceType is a non-nullable value type, the expansion is
{
ResourceType resource = expression;
try {
statement;
}
finally {
((IDisposable)resource).Dispose();
}
}
Otherwise, when ResourceType is a nullable value type or a reference type other than dynamic, the expansion is
{
ResourceType resource = expression;
try {
statement;
}
finally {
if (resource != null) ((IDisposable)resource).Dispose();
}
}
Otherwise, when ResourceType is dynamic, the expansion is
{
ResourceType resource = expression;
IDisposable d = (IDisposable)resource;
try {
statement;
}
finally {
if (d != null) d.Dispose();
}
}
Note that in each one of these expansions the cast is done anyway, so as originally stated, the as IDisposable
is unnecessary.
精彩评论