将类型强制转换为 IDisposable - 为什么?

发布于 2024-10-12 06:13:57 字数 193 浏览 6 评论 0原文

看到了这个。为什么显式转换为 IDisposable?这只是确保在退出 using 块时调用 IDisposable 的简写吗?

using (proxy as IDisposable)
{
  string s = proxy.Stuff()                                    
}

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 = proxy.Stuff()                                    
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

网名女生简单气质 2024-10-19 06:13:57

这个“技巧”(如果您可以这样称呼它)很可能是由于 proxy 的类型编译器无法验证是否真正实现了 IDisposable

using 指令的好处是,如果它的参数为 null,那么在退出时不会调用 Dispose using 语句的范围。

因此,您所显示的代码实际上是以下内容的简写:

var disposable = proxy as IDisposable;
try
{
    string s = proxy.Stuff();
}
finally
{
    if (disposable != null)
        disposable.Dispose();
}

换句话说,它表示“如果该对象实现了 IDisposable,那么当我完成以下代码段时,我需要将其释放。”

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."

很糊涂小朋友 2024-10-19 06:13:57

如果您从某处获得一个 proxy 实例,并且其静态类型未实现 IDisposable,但您知道实际类型可能会实现,并且您想确保实现这一点,则可能需要这样做它将被处置,例如

public class Proxy : ISomeInterface, IDisposable
{
    ...
}

private ISomeInterface Create() { ... }

ISomeInterface proxy = Create();

//won't compile without `as`
using(proxy as IDisposable)
{
    ...
}

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)
{
    ...
}
夏天碎花小短裙 2024-10-19 06:13:57

这是不必要的,因为 using 语句显式绑定到 IDisposable 接口,根据 MSDN 文档

提供方便的语法,确保正确使用 IDisposable 对象。

编辑C# 语言规范(第 8.13 节)为 using 语句的语法糖提供了三种可能的扩展:

以下形式的 using 语句

using (ResourceType resource = expression) statement

对应于三种可能的扩展之一。当ResourceType为不可空值类型时,扩展为

{
   ResourceType resource = expression;
   try {
      statement;
   }
   finally {
      ((IDisposable)resource).Dispose();
   }
}

否则,当 ResourceType 为可为空值类型或非动态引用类型时,扩展为

{
   ResourceType resource = expression;
   try {
      statement;
   }
   finally {
      if (resource != null) ((IDisposable)resource).Dispose();
   }
}

否则,当ResourceType为动态时,扩展为

{
   ResourceType resource = expression;
   IDisposable d = (IDisposable)resource;
   try {
      statement;
   }
   finally {
      if (d != null) d.Dispose();
   }
}

注意,在每一个扩展中,无论如何都会完成强制转换,因此如最初所述,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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文