私は複合パターンの後にオブジェクトの集合を持っています。それらはIEnumeratorで横断したいツリー構造を形成します。私は本の "Head First Design Patterns"のJavaコードを翻訳しています。私はIEnumeratorインターフェイスを実装する2つのクラスを実装しました:CompositeIteratorおよびNullIterator合成パターンにIEnumerator <T>インターフェイスを実装する方法は?
Thisは、私がC#に翻訳したいJavaコードです。
はまた、これは私の私が唯一MoveNextメソッドを(呼び出す必要がありwanted implementation of the Waitress class、)と全体のツリー構造を横断する現在のです。
私のコードは、イテレータを含むwhileループには入っておらず、ベジタリアンMenuItemオブジェクトをコンソールに出力したいと思います。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Iterator
{
class Program
{
static void Main(string[] args)
{
MenuComponent pancakeHouseMenu = new Menu("PANCAKEHOUSE MENU", "Breakfast");
MenuComponent dinerMenu = new Menu("DINER MENU", "Lunch");
MenuComponent cafeMenu = new Menu("CAFE MENU", "Dinner");
MenuComponent dessertMenu = new Menu("DESSERT MENU", "Dessert of course!");
MenuComponent allMenus = new Menu("ALL MENUS", "All menus combined");
allMenus.Add(pancakeHouseMenu);
allMenus.Add(dinerMenu);
allMenus.Add(cafeMenu);
pancakeHouseMenu.Add(new MenuItem("K&B Pancake breakfast", "pancakes with scrambled eggs, and toast", true, 2.99));
pancakeHouseMenu.Add(new MenuItem("Regular Pancake breakfast", "pancakes with fried eggs, sausage", false, 2.99));
dinerMenu.Add(new MenuItem("Veggie burguer and air fries", "Veggie burguer on a whole wheat bun, lettuce, tomato and fries", true, 3.99));
dinerMenu.Add(new MenuItem("Soup of the day", "Soup of the day with a side salad", false, 3.69));
dinerMenu.Add(dessertMenu);
dessertMenu.Add(new MenuItem("Apple pie", "Apple pie with a flakey crust, topped with vanilla ice cream", true, 1.59));
cafeMenu.Add(new MenuItem("Vegetarian BLT", "(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99));
cafeMenu.Add(new MenuItem("BLT", "Bacon with lettuce & tomato on whole wheat", false, 2.99));
Waitress waitress = new Waitress(allMenus);
waitress.PrintVegetarianMenu();
}
}
class Waitress
{
private MenuComponent AllMenus { get; set; }
public Waitress(MenuComponent allMenus)
{
AllMenus = allMenus;
}
public void PrintMenu()
{
AllMenus.Print();
}
public void PrintVegetarianMenu()
{
CompositeIterator<MenuComponent> iterator = (CompositeIterator<MenuComponent>)AllMenus.CreateIterator();
Console.WriteLine("VEGATARIAN MENU");
// this loop is never entered
while (iterator.MoveNext())
{
Console.WriteLine("inside while loop");
MenuComponent menuComponent = (MenuComponent)iterator.Current;
Console.WriteLine(menuComponent.Name);
try
{
if (menuComponent.Vegetarian)
{
menuComponent.Print();
}
}
catch (NotSupportedException e)
{
Console.WriteLine("Operation not supported.");
}
}
}
}
/*
Methods of MenuComponent class are virtual, because we sometimes want to use the default behavior. The CreateIterator method is abstract.
*/
abstract class MenuComponent
{
// Composite methods
public virtual void Add(MenuComponent menuComponent)
{
throw new NotSupportedException();
}
public virtual void Remove(MenuComponent menuComponent)
{
throw new NotSupportedException();
}
public virtual MenuComponent GetChild(int i)
{
throw new NotSupportedException();
}
// End of composite methods
// Operation methods
public virtual string Name
{
get
{
throw new NotSupportedException();
}
set
{
throw new NotSupportedException();
}
}
public virtual string Description
{
get
{
throw new NotSupportedException();
}
set
{
throw new NotSupportedException();
}
}
public virtual bool Vegetarian
{
get
{
throw new NotSupportedException();
}
set
{
throw new NotSupportedException();
}
}
public virtual double Price
{
get
{
throw new NotSupportedException();
}
set
{
throw new NotSupportedException();
}
}
public virtual void Print()
{
throw new NotSupportedException();
}
// End of operation methods
public abstract IEnumerator CreateIterator();
}
public sealed class CompositeIterator<T> : IEnumerator<T> {
private readonly Stack<IEnumerator<T>> Stack = new Stack<IEnumerator<T>>();
public CompositeIterator(IEnumerator<T> initial)
{
Stack.Push(initial);
}
public bool MoveNext()
{
while (Stack.Any())
{
if (!Stack.Peek().MoveNext())
{
Stack.Pop().Dispose();
continue;
}
var tmp = Current as IEnumerable<T>;
if (tmp != null) { Stack.Push(tmp.GetEnumerator()); }
}
return false;
}
public void Reset() { throw new NotSupportedException(); }
public T Current => Stack.Peek() != null ? Stack.Peek().Current : default(T);
object IEnumerator.Current => Current;
public void Dispose()
{
if (!Stack.Any()) { return; }
try {
foreach (var x in Stack) {
x.Dispose();
}
} catch { }
}
}
public sealed class NullIterator<T> : IEnumerator<T> {
public NullIterator() {}
public bool MoveNext()
{
return false;
}
public void Reset() { throw new NotSupportedException(); }
public T Current
{
get
{
return default(T);
}
}
object IEnumerator.Current => Current;
public void Dispose()
{
return;
}
}
// This is a tree leaf
class MenuItem : MenuComponent
{
public override string Name { get; set; }
public override string Description { get; set; }
public override bool Vegetarian { get; set; }
public override double Price { get; set; }
public MenuItem(string name, string description, bool vegetarian, double price)
{
Name = name;
Description = description;
Vegetarian = vegetarian;
Price = price;
}
public override void Print()
{
Console.Write(" " + Name);
if (Vegetarian)
{
Console.Write("(v)");
}
Console.Write(", " + Price);
Console.Write(" -- " + Description);
}
public override IEnumerator CreateIterator()
{
return new NullIterator<MenuItem>();
}
}
// This is a tree node
class Menu : MenuComponent
{
public List<MenuComponent> MenuComponents;
public override string Name { get; set; }
public override string Description { get; set; }
public Menu(string name, string description)
{
Name = name;
Description = description;
MenuComponents = new List<MenuComponent>();
}
public override void Add(MenuComponent menuComponent)
{
MenuComponents.Add(menuComponent);
}
public override void Remove(MenuComponent menuComponent)
{
MenuComponents.Remove(menuComponent);
}
public override MenuComponent GetChild(int i)
{
return MenuComponents[i];
}
// we have to use recursion to print all the hierarchy
public override void Print()
{
Console.Write("\n" + Name);
Console.WriteLine(", " + Description);
Console.WriteLine("--------------");
IEnumerator iterator = MenuComponents.GetEnumerator();
while(iterator.MoveNext())
{
MenuComponent menuComponent = (MenuComponent)iterator.Current;
menuComponent.Print();
Console.Write("\n");
}
}
public override IEnumerator CreateIterator()
{
return new CompositeIterator<MenuComponent>(MenuComponents.GetEnumerator());
}
}
}
あなたのコードはどこにでも 'IEnumerable'言及していない - あなたは* *現時点ではそれを実装しようとしていません。次に、あなたは 'IEnumerator .Current'を実装していません。コンパイラが不満を言っているので... –
' IEnumerator 'ではなく、' IEnumerable 'が必要でしょうか? –
Groo
@Groo私はただ動作するものがほしいだけです。私はC#の初心者です。私はこの質問のタイトルを間違えました。 – freinn