This can happen when an interface is explicitly implemented. First, a basic example of an implicitly implemented interface:
public interface IFoo
{
void FooTheBar();
}
public class ImplicitImplementer : IFoo
{
public void FooTheBar()
{
// ...
}
}
This can be used the way you expect it to, both by its concrete type and the interface:
ImplicitImplementer a = new ImplicitImplementer();
a.FooTheBar(); // works
IFoo b = new ImplicitImplementer();
b.FooTheBar(); // works
But when you explicitly implement an interface, you must use the interface type.
public class ExplicitImplementer : IFoo
{
public void IFoo.FooTheBar() // Notice the "IFoo."
{
// ...
}
}
Notice the consequences:
ExplicitImplementer a = new ExplicitImplementer();
a.FooTheBar(); // ERROR!
IFoo b = new ExplicitImplementer();
b.FooTheBar(); // works
That's just how it works. I suspect that your SqlBulkCopy
class explicitly implements IDisposable
, which means you're going to have to cast it to the correct interface:
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_bulkCopy != null)
(_bulkCopy as IDisposable).Dispose();
}
}
I prefer the as
syntax, but you can use (IDisposable) _bulkCopy
if you prefer. You can actually slightly improve the flow of the code here:
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
(_bulkCopy as IDisposable)?.Dispose();
}
}
This prevents exceptions both in the case of _bulkCopy
being null or _bulkCopy
no longer implementing IDisposable
anymore. It disposes if it can, and otherwise it does nothing.
It may seem weird why this is ever useful, and it doesn't quite seem necessary in your case. Explicit implementation is only useful when a class implements multiple interfaces that have a clashing interface member, e.g.:
public interface IFoo
{
void FooTheBar();
}
public interface IBar
{
void FooTheBar();
}
public class FooBar : IFoo, IBar
{
public void FooTheBar()
{
Console.WriteLine("IFoo or IBar?");
}
}
This code actually works, but the same method will be called regardless of whether you do:
IFoo a = new FooBar();
a.FooTheBar(); // "IFoo or IBar?"
IBar b = new FooBar();
b.FooTheBar(); // "IFoo or IBar?"
But what if you want these two methods to be separate? Well, then you explicitly label each method implementation as belonging to a specific interface. That's what explicit implementation is.
public class FooBar : IFoo, IBar
{
public void IFoo.FooTheBar()
{
Console.WriteLine("IFoo");
}
public void IBar.FooTheBar()
{
Console.WriteLine("IBar");
}
}
And then you'll see:
IFoo a = new FooBar();
a.FooTheBar(); // "IFoo"
IBar b = new FooBar();
b.FooTheBar(); // "IBar"
But since you've restricted these methods to the specific interfaces, FooBar
itself cannot resolve to a specific FooTheBar
method anymore, hence the error you're faced with. It's a consequence of a solution to another problem (i.e. overlapping interfaces).