Inheriting an interface with an internal database

I was wondering if there is a way to do the following:

In my project, I defined an interface, say IFruit. This interface has the public method GetName (). I also declare an IApple interface that implements IFruit and provides another method like GetAppleType () or something else. Eat more fruits like Ibanana, Jerry, whatever.

Now outside, I only want to be able to use the actual implementation of the fruit, not IFruit itself. But I can’t declare the IFruit interface private or internal, since the inherited interfaces will say: "Cannot be implemented because the base class is less accessible."

I know this is possible with abstract implementations, but this is not an option in this case: I really need to use interfaces. Is there such an option?

Update I think my example needs clarification :) I use MEF to load interface implementations. Downloaded collections are based on IApple, IBanana, ICherry, etc. But IFruit itself is useless; I cannot use classes based only on this interface. Therefore, I was looking for a way to prevent other developers from implementing exclusively IFruit, believing that their class will be loaded (which will not). So basically it comes down to:

internal interface IFruit { public string GetName(); } 

public interface IApple : IFruit { public decimal GetDiameter(); }

public interface IBanana : IFruit { public decimal GetLenght(); }

But this does not compile due to the less accessible base interface.

+7
source share
3 answers

It is not possible to do what you are trying to, but you can disable people using the IFruit interface with the [Obsolete] attribute, with a message to say why.

On your IBanana, IApple, ... interfaces, disable the deprecated warning.

 [Obsolete] public interface IFruit { ... } #pragma warning disable 612 public interface IBanana : IFruit { ... } #pragma warning restore 612 
+2
source

One way to guarantee this unintentionally is to make IFruit internal your assembly, and then use some kind of adapter to properly wrap the type:

 public interface IApple { string GetName(); } public interface IBanana { string GetName(); } internal interface IFruit { string GetName(); } class FruitAdaptor: IFruit { public NameAdaptor(string name) { this.name = name; } private string name; public string GetName() { return name; } } // convenience methods for fruit: static class IFruitExtensions { public static IFruit AsFruit(this IBanana banana) { return new FruitAdaptor(banana.GetName()); } public static IFruit AsFruit(this IApple apple) { return new FruitAdaptor(apple.GetName()); } } 

Then:

 MethodThatNeedsFruit(banana.AsFruit()); 

You can also easily extend this to lazily call GetName on an adapted object if the name can change over time.


Another option would be to only check for DEBUG, which loads all IFruit implementers and then throws an exception if one of them does not actually implement IBanana / IApple . Since these classes seem to be intended for internal use within your company, this should prevent someone from accidentally implementing the wrong thing.

+5
source

If you have some kind of code (assuming I understand your state correctly), something like this:

 public class WaterMellon : IFruit, IVegetables... { } 

and you want the user of your infrastructure access to only apply IFruit methods, for me there is no other known method, and then it just executes.

 IFruit fruit = new WaterMelon(); fruit. //CAN ACCESS ONLY TO FRUIT IMPLEMNTATION AVAILABLE IN WATERMELON 

If this is not what you are asking for, please specify.

0
source

All Articles