如何在单个列表中存储不同的对象 [英] How can I store different objects in a single list

查看:83
本文介绍了如何在单个列表中存储不同的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个类,一个Arc类和一个Line类

I have two classes an Arc class and a Line class

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(){}
}

但我想存储弧线和同一列表中的行,所以我尝试了这样的界面

But I want to store arcs and lines in the same list, so I tried an interface like this

public interface Entity
{
     double StartX();
     double StratY();
     double EndX();
     double EndY();
}

然后我为每个类添加了适当的方法并添加了代码以使用接口。现在我可以将两种类型的对象添加到列表中,但我想从线对象获取长度,并且不希望将长度方法添加到弧或接口。我唯一的选择是将线对象强制转换回这样的线对象吗?

Then I added the appropriate methods to each class and added the code to use the interface. Now I can add both types of objects to a list, but I want to get the length from a line object and don't want to add a length method to the arc or the interface. Is my only option to cast the line object back to a line object like this?

List<Entity> entities = new List<Entity>();
entities.Add(new Line(10,10,5,5));
Line myLine = (Line)Entities[0]
double length = myLine.Length();

*假设我在行类中有所有正确的方法。

或是否有更好/不同的方法来做到这一点?

*Assuming I have all the proper methods in the line class.
Or is there a better/different way to do this?

推荐答案


还是有更好的/不同的
的方法是这样做的吗?

Or is there a better/different way to do this?

如果您的对象来自公共类,那么您可以将它们存储在同一个集合中。为了在不丢弃类型安全的情况下对您的对象执行任何有用的操作,您需要实现访问者模式

If your objects descend from a common class, then you can store them in the same collection. In order to do anything useful with your objects without throwing away type safety, you'd need to implement the visitor pattern:

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);
    }
}

一旦到位,您就创建了EntityVisitor的实例每当你需要对你的列表做一些有用的事情时:

Once that's in place, you create an instance of EntityVisitor whenever you need to do something useful with your list:

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);
    }
}






值得一提的是,如果您愿意尝试新语言,那么F#标记的工会+模式匹配是访客模式的便捷替代方案

这篇关于如何在单个列表中存储不同的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆