Reputation: 21419
Straight to the problem: I have a class that implements two interfaces:
public class A : Interface1, Interface2{
// Interface 1 implementation...
// Interface 2 implementation...
}
Is there a way (without creating another new class) to make Interface1 implementation internal and hide it from other components (only Interface2 will stay public)?
EDIT: Some more useful infos: Interface1
and Interface2
are defined as public in another core component and cannot be changed.
Thanks in advance,
Upvotes: 17
Views: 9740
Reputation: 19203
There is no way to restrict casting operations to an interface. However you could provide a wrapper class that implements the interface but isn't normally available.
For instance:
public class Foo
{
private IFoo wrap = new WrapFoo(this);
internal IFoo GetIFoo()
{
return wrap;
}
private class WrapFoo : IFoo
{
public WrapFoo(Foo parent)
{
//Save parent
}
public void DoSomething()
{
//Implement interface
}
}
}
Another more complicated way would be to use code signing to verify that the caller is the library and throwing an exception otherwise.
Upvotes: 3
Reputation: 126864
While you can make the interface itself internal, the methods would still be part of the public API. What you can elect to do is explicit interface implementation, so that the API defined by the interface is only visible via the interface, and not via the class.
interface IFoo
{
void M();
}
interface IBar
{
void X();
}
public class Bar : IBar, IFoo
{
public void X() // part of the public API of Bar
{
}
void IFoo.M() // explicit implementation, only visible via IFoo
{
}
}
Bar bar = new Bar();
bar.X(); // visible
bar.M(); // NOT visible, cannot be invoked
IFoo foo = bar;
foo.M(); // visible, can be invoked
Beyond this, if you need the world to never have any idea that the class supports the interface, then you would simply need to not have the class implement the interface. Interfaces are for the intent of broadcasting that a given object supports given behaviors, explicitly or otherwise. If that's not what you want, you need to go a different direction. It could simply be that the class implements the behaviors as private implementation details, sans interface. Another approach is to shovel those implementations into a private nested class.
public class Bar : IBar
{
Foo foo = new Foo();
public void X() { }
public void DoSomething()
{
this.foo.M(); // invokes method of instance of nested class
}
class Foo : IFoo
{
public void M() { }
}
}
Under this approach, the world never knows that a class fulfills the interface contract, because it technically doesn't. The contract is fulfilled by Foo
, and the world cannot see Foo
. However, the benefit is that if the class needs to invoke externally defined methods that require the interface, it can still pass the nested class instance to those methods.
Upvotes: 36