我有两个类,一个是 Arc 类,一个是 Line 类
public class Arc
{
protected double startx;
protected double starty;
protected double endx;
protected double endy;
protected double radius;
public Arc(){}
}
public class Line
{
protected double startx;
protected double starty;
protected double endx;
protected double endy;
protected double length;
public Line(){}
}
Run Code Online (Sandbox Code Playgroud)
但我想将弧和线存储在同一个列表中,所以我尝试了这样的界面
public interface Entity
{
double StartX();
double StratY();
double EndX();
double EndY();
}
Run Code Online (Sandbox Code Playgroud)
然后,我向每个类添加了适当的方法,并添加了使用该接口的代码。现在我可以将两种类型的对象添加到列表中,但我想从线对象获取长度,并且不想向弧或界面添加长度方法。我是将线条对象转换回这样的线条对象的唯一选择吗?
List<Entity> entities = new List<Entity>();
entities.Add(new Line(10,10,5,5));
Line myLine = (Line)Entities[0]
double length = myLine.Length();
Run Code Online (Sandbox Code Playgroud)
*假设我在线路类中拥有所有正确的方法。
或者有更好/不同的方法来做到这一点?
Jul*_*iet -2
或者有更好/不同的方法来做到这一点?
如果您的对象源自公共类,那么您可以将它们存储在同一个集合中。为了对你的对象做任何有用的事情而不放弃类型安全,你需要实现访问者模式:
public interface EntityVisitor
{
void Visit(Arc arc);
void Visit(Line line);
}
public abstract class Entity
{
public abstract void Accept(EntityVisitor visitor);
}
public class Arc : Entity
{
protected double startx;
protected double starty;
protected double endx;
protected double endy;
protected double radius;
public override void Accept(EntityVisitor visitor)
{
visitor.Visit(this);
}
}
public class Line : Entity
{
protected double startx;
protected double starty;
protected double endx;
protected double endy;
protected double length;
public override void Accept(EntityVisitor visitor)
{
visitor.Visit(this);
}
}
Run Code Online (Sandbox Code Playgroud)
一旦完成,只要您需要对列表执行一些有用的操作,就可以创建 EntityVisitor 的实例:
class EntityTypeCounter : EntityVisitor
{
public int TotalLines { get; private set; }
public int TotalArcs { get; private set; }
#region EntityVisitor Members
public void Visit(Arc arc) { TotalArcs++; }
public void Visit(Line line) { TotalLines++; }
#endregion
}
class Program
{
static void Main(string[] args)
{
Entity[] entities = new Entity[] { new Arc(), new Line(), new Arc(), new Arc(), new Line() };
EntityTypeCounter counter = entities.Aggregate(
new EntityTypeCounter(),
(acc, item) => { item.Accept(acc); return acc; });
Console.WriteLine("TotalLines: {0}", counter.TotalLines);
Console.WriteLine("TotalArcs: {0}", counter.TotalArcs);
}
}
Run Code Online (Sandbox Code Playgroud)
就其价值而言,如果您愿意尝试新语言,那么 F# 的标记联合 + 模式匹配是访问者模式的便捷替代方案。
| 归档时间: |
|
| 查看次数: |
16968 次 |
| 最近记录: |