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
语句,但这是唯一的方法吗?我不想这样做,因为这意味着我可能不得不继续创建该对象
我知道我也可以围绕这个接口包装一个接口,但是还有其他方法吗?
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
方法,因此会遇到错误。这是解决另一个问题(即重叠的界面)的结果。