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
。
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
。