visit
using System;
namespace HidingMembersViaExplicitInterfaceImplementation
{
public enum FruitType
{
Apple,
Orange,
Banana
}
public class Factory
{
public static Fruit Create(FruitType type)
{
// the Factory class can modify the properties because it has access to
// the private IFruitSetters interface
var fruit = new Fruit();
((IFruit)fruit).fruitType = type;
switch (type)
{
case FruitType.Apple:
((IFruit)fruit).color = "Red";
break;
case FruitType.Banana:
((IFruit)fruit).color = "Yellow";
break;
case FruitType.Orange:
((IFruit)fruit).color = "Orange";
break;
}
((IFruit)fruit).DoOtherHiddenThings();
return fruit;
}
// define a private interface containing the setters.
private interface IFruit
{
// define the setter in the private interface
string color { set; }
FruitType fruitType { set; }
void DoOtherHiddenThings();
}
// This is the inner class. It has members color and fruitType that should not be modified
// by clients, but should be modified by the factory.
public class Fruit : IFruit
{
private string pColor;
private FruitType pFruitType;
// explicitly implement the setters
string IFruit.color { set { pColor = value; } }
FruitType IFruit.fruitType { set { pFruitType = value; } }
void IFruit.DoOtherHiddenThings()
{
//Does nothing. Just showing how to hide methods too.
}
// create a public getters
public string Color { get { return pColor; } }
public FruitType FruitType { get { return pFruitType; } }
}
}
class Program
{
static void Main(string[] args)
{
Factory.Fruit apple = Factory.Create(FruitType.Apple);
// can only read color and fruitType because only the getter is public
// and IFruit is private to Factory
string fruitColor = apple.Color;
FruitType type = apple.FruitType;
}
}
}
First, I call the factory’s Create method and specify via an enumerator what type of fruit I want returned to me. Then, I set hidden properties via the explicit interface implementation, and even call a similarly hidden method that does nothing. The interface IFruit is hidden to the client, being private, and is only accessible from within the factory’s create method. This ensure that I always get a red Apple, a yellow Banana, and orange Orange. This same technique can be utilized to always create your own classes instances in a valid state with value default data, as well as protect read-only members.
Yet another benefit can be found using this technique. Often, large interface definitions force a class to implement methods that, for our purposes, make no logical sense for our usage. By implementing them explicitly, we effectively hide those methods from the visible public class instance.
About the author...
Lee McGraw has worked in the technology industry for over 30 years, first developing on an Apple II. He has served as Enterprise Developer and Architect for entities such as AIG, Ford, Coke, USAA, US Department of Defense and Energy, and many banks.