在致电 Dispose()之前,选择 IDisposable 的原因是什么?
public interface ITransaction : IDisposable
{}
.
.
.
//in some other class:
public void EndTransaction(ITransaction transaction)
{
if (transaction != null)
{
(transaction as IDisposable).Dispose();
// is the following code wrong? transaction.Dispose()
transaction = null;
}
}
这是ITransaction的具体实现之一:
public class NHibernateTransaction : ITransaction
{
public NHibernateTransaction(NHibernate.ITransaction transaction)
{
this.Transaction = transaction;
}
protected NHibernate.ITransaction Transaction { get; private set; }
public void Dispose()
{
if ( this.Transaction != null )
{
(this.Transaction as IDisposable).Dispose(); // this is NHibernate ITransaction object
this.Transaction = null;
}
}
}
我已经在存储库模式的开源实现中多次看到该代码片段,我似乎无法理解演员背后的原因。直接在 if子句中调用 transaction.Dispose()应该可以正常工作。我错过了什么吗?
原始代码可以在这里找到: NHibernateTransaction.cs
答案 0 :(得分:3)
由于ITransaction
继承自IDisposable
,实施者可能已将IDisposable
实施为explicit interface implementation,在这种情况下,需要强制转换才能访问IDisposable.Dispose
实施成员。
在这种情况下,强制转换可确保调用将调用ITransaction
方法。演员阵容完成了所有基地。
如果IDisposable
未从Dispose
继承,但实施者会继承,则IDisposable
需要强制转换才能进行调用。如果实施者没有实施{{1}},则这种情况可能会失败(抛出异常)。
答案 1 :(得分:0)
在从IDisposable派生的界面上调用Dipose()
时,没有区别。
在实施Dispose()
的类上调用IDisposable
时可能会有所不同,因为方法Dispose()
可以明确实现。
答案 2 :(得分:0)
我不经常这样做,但是当我理解Oded现在试图说的话时,我打破了我原来的全部答案。他们的意图是解决这个问题:
namespace StackOverflow7051864
{
using System;
public interface ITransaction : IDisposable {}
public interface ITryToConfuseDispose
{
void Dispose();
}
public class Transaction : ITransaction, ITryToConfuseDispose
{
void IDisposable.Dispose()
{
Console.WriteLine("Happy");
}
void ITryToConfuseDispose.Dispose()
{
Console.WriteLine("Confused");
}
}
class Program
{
static void Main(string[] args)
{
EndTransaction(new Transaction());
}
public static void EndTransaction(ITransaction transaction)
{
(transaction as IDisposable).Dispose();
transaction.Dispose();
}
}
}
'transaction.Dispose()'调用什么?它调用IDisposable.Dispose()
问题是,由于与EndTransaction的合同是ITransaction,因此它将始终调用IDisposable版本。