Dispose 方法不允许对象参与 C# 中的使用。为什么?

Dispose method does not allow the object to participate in the using in C#. Why?

Dispose方法不允许对象参与C#中的使用。为什么?

根据 C#CLR

If a dynamic expression is specified as the collection in a foreach statement or as a resource in a using statement, the compiler will generate code that attempts to cast the expression to the non-generic System.IEnumerable interface or to the System.IDisposable interface, respectively. If the cast succeeds, the expression is used and the code runs just fine. If the cast fails, a Microsoft.CSharp.RuntimeBinder.RuntimeBinderException exception is thrown.

所以,我正在尝试以下操作:

using System;

namespace myprogram
{
    delegate void VoidRes();
    class Program
    {
        static void Main(string[] args)
        {

            dynamic a = new
            {
                Dispose = new VoidRes
                (
                    delegate () { Console.WriteLine("in Dispose"); }
                )
            };

            using(a) {
                Console.WriteLine("foo");
            }
        }
    }
}

我收到一个错误:

Unhandled exception. Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot implicitly convert type '<>f__AnonymousType4' to 'System.IDisposable' at CallSite.Target(Closure , CallSite , Object ) at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)

这很奇怪,因为我认为为了满足 IDisposable 接口,实现 Dispose 方法就足够了(正是我在匿名类型中所做的)。

我在这里错过了什么?

您的匿名类型没有实现 IDisposable 接口只是因为它具有 IDisposable 接口所具有的方法。匿名类型不能实现接口。看这里:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/anonymous-types

其中指出:

"Anonymous types are class types that derive directly from object, and that cannot be cast to any type except object."

实现 IDisposable 就足够了,但它并没有发生在您的代码中的任何地方。 C# 中的接口实现是通过创建 class/struct 并显式指示接口类型来完成的。对象具有相同的成员(属性、方法等)来匹配接口是不够的。 (这种行为称为鸭子打字,存在于其他一些语言中。)

即使在 C# 中可以使用回避类型,这种特殊情况仍然行不通。这是因为 new { Dispose = ... } 使用名为 Dispose 的 属性(不是方法)创建了匿名 class 的实例。因此,不满足 IDisposable 接口的约定。

同样匿名的 classes 不实现接口,特别是 IDisposable