Piszę małą bibliotekę struktur danych w języku C# i mam problem z architekturą. Zasadniczo mam klasy, która implementuje odwiedzający, i istnieje wiele możliwych implementacji odwiedzających:Jak symulować anonimowe klasy w C#
public interface ITreeVisitor<T, U>
{
U Visit(Nil<T> s);
U Visit(Node<T> s);
}
public abstract class Tree<T> : IEnumerable<T>
{
public readonly static Tree<T> empty = new Nil<T>();
public abstract U Accept<U>(ITreeVisitor<T, U> visitor);
}
public sealed class Nil<T> : Tree<T>
{
public override U Accept<U>(ITreeVisitor<T, U> visitor) { return visitor.Visit(this); }
}
public sealed class Node<T> : Tree<T>
{
public Tree<T> Left { get; set; }
public T Value { get; set; }
public Tree<T> Right { get; set; }
public override U Accept<U>(ITreeVisitor<T, U> visitor) { return visitor.Visit(this); }
}
Zawsze chcę przekazać w odwiedzającego, muszę utworzyć klasę odwiedzających, implementować interfejs i przekazać to w ten sposób:
class InsertVisitor<T> : ITreeVisitor<T, Tree<T>> where T : IComparable<T>
{
public T v { get; set; };
public Tree<T> Visit(Nil<T> s)
{
return new Node<T>() { Left = Tree<T>.empty, Value = v, Right = Tree<T>.empty };
}
public Tree<T> Visit(Node<T> s)
{
switch (v.CompareTo(s.Value))
{
case -1: return new Node<T>() { Left = Insert(v, s.Left), Value = s.Value, Right = s.Right };
case 1: return new Node<T>() { Left = s.Left, Value = s.Value, Right = Insert(v, s.Right) };
default: return s;
}
}
}
public static Tree<T> Insert<T>(T value, Tree<T> tree) where T : IComparable<T>
{
return tree.Accept<Tree<T>>(new InsertVisitor<T>() { v = value });
}
nie lubię pisać, że dużo kodu szablonowe, bo robi się bardzo brudny, gdy masz numer nietrywialne wdrożeń gości.
chcę napisać coś podobnego do anonymous classes Java (kod koncepcja):
public static Tree<T> Insert<T>(T v, Tree<T> tree) where T : IComparable<T>
{
return tree.Accept<Tree<T>>(new InsertVisitor<T>()
{
public Tree<T> Visit(Nil<T> s) { return new Node<T>() { Left = Tree<T>.empty, Value = v, Right = Tree<T>.empty }; }
public Tree<T> Visit(Node<T> s)
{
switch (v.CompareTo(s.Value))
{
case -1: return new Node<T>() { Left = Insert(v, s.Left), Value = s.Value, Right = s.Right };
case 1: return new Node<T>() { Left = s.Left, Value = s.Value, Right = Insert(v, s.Right) };
default: return s;
}
}
};
}
Czy istnieje jakiś sposób, aby symulować anonimowych klas z implementacji interfejsu w C#?
chcieć wyjaśnić co anonimowy interfejs. Obawiam się, że nie mam pojęcia, co to znaczy. – Noldorin
@Noldorin: anonimowy * interfejs * nie jest najlepszym wyborem słów, mam na myśli anonimową * klasę *. W Javie jest funkcja, w której można implementować interfejsy w locie bez potrzeby używania nazwanej klasy - chciałbym zrobić coś podobnego w języku C#. – Juliet
Jesteś pewien, że nie możesz zrobić z delegatami? –