Ответ Марка довольно хорош и хороший старт ... Я бы немного расширил. Я, вероятно, не буду использовать массив для фруктов, так как вы будете добавлять, удалять и т. Д. ... возможно, проще реализовать со списком или похожим. Кроме того, Лэйн говорит, что ему нужно несколько фруктов в некоторых соковыжималках .. это немного усложняет ситуацию и дает нам некоторые решения.
Если он всегда будет не более двух плодов, я бы, вероятно, просто сделать два Соковыжималка классы, аналогичные тем, в ответ Марка:
public interface IFruit
{
string Name {get;}
}
public class Apple : IFruit
{
public string Name { get {return "Apple";} }
}
public class Pear : IFruit
{
public string Name { get {return "Pear";} }
}
public class Juicer<IFruit>
{
private IList<IFruit> fruits;
public Juicer(IList<IFruit> fruits)
{
this.fruits = fruits;
}
public int FruitCount
{
get { return this.fruits.Count; }
}
// Other members can go here...
}
public class TwoFruitJuicer<IFruit, IFruit2>
{
private IList<IFruit> fruits;
private IList<IFruit2> fruits2;
public TwoFruitJuicer(IList<IFruit> fruits, IList<IFruit2> fruits2)
{
this.fruits = fruits;
this.fruits2 = fruits2;
}
public int FruitCount
{
get { return this.fruits.Count + this.fruits2.Count; }
}
// Other members can go here...
}
Но, говорят, что вы хотели 3 или 4 различных соковыжималки комбинированные .. ,
public class MulitJuicer
{
private IList<Juicer<IFruit>> _juicers;
public MulitJuicer(IList<Juicer<IFruit>> juicers)
{
this._juicers = juicers;
}
public int FruitCount
{
get {
int allFruitCount = 0;
foreach (var j in _juicers)
{
allFruitCount += j.FruitCount;
}
return allFruitCount;
}
}
}
Однако, это, вероятно, будет довольно трудно использовать, много списков внутри списков для отслеживания создания и этажерки ... что, если вы хотите только один раз соковыжималки, что вы могли бы просто сбросить кучу фруктов в? Мы можем использовать Reflection, чтобы убедиться, что только разрешенные фрукты положить в соковыжималку:
public class MultiFruitJuicer
{
private IList<Type> _juiceTypes;
private IList<IFruit> _fruits;
public MultiFruitJuicer(IList<Type> juiceTypes, IList<IFruit> fruits)
{
_juiceTypes = juiceTypes;
_fruits = fruits;
if (!ValidateFruits())
{
//you may not want to actually throw here...
throw new Exception("Not all proper fruit types");
}
}
public bool ValidateFruits()
{
//there are about a million ways to do this... this is probably not the best...
foreach(var f in _fruits)
{
if (!_juiceTypes.Contains(f.GetType()))
{
return false;
}
}
return true;
}
public int FruitCount
{
get { return this._fruits.Count; }
}
}
Две вещи, которые заставили меня downvote этот ответ был ** а) ** unbased рекомендация Singleton в 2015 году ** б) ** Там в нет никаких указаний на то, что принудительное использование плодов под общим интерфейсом и/или базовым классом оправдано. Это имеет недостаток в закрытии доступа соковыжималки из добавленных типов, не зная этого кода. Во всяком случае, я бы ожидал, что доступ к типовым соковыжималкам будет стираться с типом, что рекомендует другой ответ. –
@bartek Интерфейс 'Fruit' будет следить за тем, чтобы при добавлении новых типов фруктов остальная часть кода по-прежнему будет работать с ним -' Соковыжималка'. Более того, это позволит вам иметь коллекцию фруктов. Базовый класс поможет избежать повторения общего для всех полей, свойств, методов. – ekostadinov
Но это также означает, что вы не сможете адаптировать любые классы, которые не наследуются от интерфейса Fruir или реализации фруктов, без написания сложных адаптеров, чего можно избежать с помощью дженериков. –