在调用Dispose()之前强制转换为IDisposable

时间:2011-08-13 16:45:21

标签: c# casting idisposable

在致电 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

3 个答案:

答案 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版本。