[英]How do I simulate anonymous classes in C#
我正在用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); }
}
每当我想传递访问者时,我都必须创建一个访问者类,实现该接口,然后像这样传递它:
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 });
}
我不喜欢编写那么多样板代码,因为当访问者实现的数量非常少时,它会变得非常混乱。
我想写一些类似于匿名类Java (概念代码)的东西:
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;
}
}
};
}
有没有办法用C#中的接口实现模拟匿名类?
您可以将类的“行为”部分从针对接口定义的方法更改为在适当的时候调用的委托,并通过传递新的委托来创建新的访问者-从而招募匿名函数来完成匿名类的工作。
草图代码(未经测试,您可以根据需要进行清理):
class CustomVisitor<T> : ITreeVisitor<T, Tree<T>> where T : IComparable<T>
{
public T v { get; set; };
public Func<Nil<T>, Tree<T>> VisitNil { get; set; }
public Func<Node<T>, Tree<T>> VisitNode { get; set; }
public Tree<T> Visit(Nil<T> s) { return VisitNil(s); }
public Tree<T> Visit(Node<T> s) { return VisitNode(s); }
}
public static Tree<T> Insert<T>(T v, Tree<T> tree) where T : IComparable<T>
{
return tree.Accept<Tree<T>>(new CustomVisitor<T> {
VisitNil = s =>
return new Node<T>() { Left = Tree<T>.empty, Value = v, Right = Tree<T>.empty }; }
VisitNode = 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;
}
}
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.