c# - 如何在 C# 类的具体实现上调用 Dispose
问题描述
如果我使用以下结构:
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
为 null 或_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
方法,因此您将面临错误。这是解决另一个问题(即重叠接口)的结果。
推荐阅读
- tensorflow - MobileNet:验证精度高,预测结果差
- python - 以递归方式将返回值添加到列表中
- tomcat - 即使它正在运行也无法连接到 Tomcat
- node.js - 存储过程如何插入/上传到数据库
- python - 当变量设置为 False 时,为什么井字游戏中的 while-loop 不会结束?
- github - 如何阻止 LGTM 包装 qmake
- java - 用 Thymeleaf 在另一个表中填充内表
- javascript - 如何按总分对对象数组进行排序
- c# - 光子中的 RPC 不通过网络发送数据
- jsf - ignoreAutoUpdate 在 PrimeFaces 中不起作用