如何在C#类的具体实现上调用Dispose [重复]

问题描述 投票:-3回答:1
如果我使用以下结构:

public class TestClass : IDisposable { private SqlBulkCopy _bulkCopy; public TestClass(SqlConnection connection) { _bulkCopy = new SqlBulkCopy(connection); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposing) { if (_bulkCopy != null) _bulkCopy.Dispose(); // Cannot call dispose as this is a concrete implementation } } }

我无法访问我的_bulkCopy对象上的dispose函数。

我知道我可以使用using语句,但这是唯一的方法吗?

我不想这样做,因为这意味着我可能不得不继续创建该对象

我知道我也可以围绕这个接口包装一个接口,但是还有其他方法吗?

c# dispose
1个回答
2
投票
可能会发生when an interface is explicitly implemented。首先,一个隐式实现的接口的基本示例:

public interface IFoo { void FooTheBar(); } public class ImplicitImplementer : IFoo { public void FooTheBar() { // ... } }

这可以按照您期望的方式使用,无论是它的具体类型还是界面:

ImplicitImplementer a = new ImplicitImplementer(); a.FooTheBar(); // works IFoo b = new ImplicitImplementer(); b.FooTheBar(); // works

但是当您明确实现接口时,您

必须使用接口类型。

public class ExplicitImplementer : IFoo { public void IFoo.FooTheBar() // Notice the "IFoo." { // ... } }
注意后果:

ExplicitImplementer a = new ExplicitImplementer(); a.FooTheBar(); // ERROR! IFoo b = new ExplicitImplementer(); b.FooTheBar(); // works

这就是它的工作方式。我怀疑您的SqlBulkCopy类显式实现了IDisposable,这意味着您将不得不将其强制转换为正确的接口:

protected virtual void Dispose(bool disposing) { if (disposing) { if (_bulkCopy != null) (_bulkCopy as IDisposable).Dispose(); } }

我更喜欢as语法,但是如果愿意,可以使用(IDisposable) _bulkCopy。您实际上可以在这里稍微改善代码流程:

protected virtual void Dispose(bool disposing) { if (disposing) { (_bulkCopy as IDisposable)?.Dispose(); } }

这可以防止在_bulkCopy为空或_bulkCopy不再实现IDisposable的情况下的异常。如果可能,它将进行处置,否则将不执行任何操作。


这似乎有用的原因似乎很奇怪,而且在您的情况下似乎没有必要。显式实现仅在类实现具有冲突接口成员的多个接口时才有用,例如:]

public interface IFoo { void FooTheBar(); } public interface IBar { void FooTheBar(); } public class FooBar : IFoo, IBar { public void FooTheBar() { Console.WriteLine("IFoo or IBar?"); } }

此代码实际上有效,但是无论您是否这样做,都将调用相同的方法:

IFoo a = new FooBar(); a.FooTheBar(); // "IFoo or IBar?" IBar b = new FooBar(); b.FooTheBar(); // "IFoo or IBar?"

但是如果您想将这两种方法

分开]怎么办?好了,然后您将每个方法实现显式标记为属于特定接口。这就是显式实现。public class FooBar : IFoo, IBar { public void IFoo.FooTheBar() { Console.WriteLine("IFoo"); } public void IBar.FooTheBar() { Console.WriteLine("IBar"); } }

然后您将看到:

IFoo a = new FooBar(); a.FooTheBar(); // "IFoo" IBar b = new FooBar(); b.FooTheBar(); // "IBar"

但是由于您已将这些方法限制为特定的接口,因此FooBar本身无法再解析为特定的FooTheBar方法,因此会遇到错误。这是解决另一个问题(即重叠的界面)的结果。
© www.soinside.com 2019 - 2024. All rights reserved.