Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Internal Interface implementation

Tags:

c#

.net

interface

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,

like image 851
GETah Avatar asked Nov 22 '11 16:11

GETah


People also ask

What is internal interface?

(1) A connection to a device inside the computer's cabinet. Contrast with external interface. (2) A connection to the LAN side of a router.

Can we have internal interface C#?

In C#, interfaces can only specify public properties and functions. However, especially when making libraries to be used by other projects, it is often beneficial to have internal interfaces (specifying functions that should also be marked internal, rather than public).

What is implicit interface implementation?

An implicit interface implementation is where you have a method with the same signature of the interface. An explicit interface implementation is where you explicitly declare which interface the method belongs to.

What is implementation of interface in C#?

On implementation of an interface, you must override all of its methods. Interfaces can contain properties and methods, but not fields/variables. Interface members are by default abstract and public. An interface cannot contain a constructor (as it cannot be used to create objects)


2 Answers

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.

like image 195
Anthony Pegram Avatar answered Oct 05 '22 22:10

Anthony Pegram


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.

like image 27
Guvante Avatar answered Oct 05 '22 22:10

Guvante