统一检查具有相似项目的不同列表

时间:2015-03-04 14:08:32

标签: c# collections

我的代码正在爆炸,也许你可以帮助我。我的班级Painter有一些对象列表:

public class Painter
{
    private readonly MyCar[] cars = new MyCar[5];
    private readonly MyHouse[] houses = new MyHouse[6];
    private readonly MyPaper[] papers = new MyPaper[7];
}

public class MyCar
{
    public void Paint(System.Drawing.Color color) { /* ... */ }
}
public class MyHouse
{
    public void Paint(System.Drawing.Color color) { /* ... */ }
}
public class MyPaper
{
    public void Paint(System.Drawing.Color color) { /* ... */ }
}

我添加了一个允许绘制其中一个对象的方法:

public class Painter
{
    private readonly MyCar[] cars = new MyCar[5];
    private readonly MyHouse[] houses = new MyHouse[5];
    private readonly MyPaper[] papers = new MyPaper[5];

    public void Paint(ObjectType type, int index, System.Drawing.Color color)
    {
        switch (type)
        {
            case ObjectType.Car: this.cars[index].Paint(color); break;
            case ObjectType.House: this.houses[index].Paint(color); break;
            case ObjectType.Paper: this.papers[index].Paint(color); break;
        }
    }

    public enum ObjectType
    {
        Car,
        House,
        Paper
    }
}

到目前为止一切合理,但我想检查索引是否超过相应数组的长度。

    public bool Paint(ObjectType type, int index, System.Drawing.Color color)
    {
        switch (type)
        {
            case ObjectType.Car:
                if (index < this.cars.Length)
                {
                    this.cars[index].Paint(color);
                    return true;
                }

                break;

            case ObjectType.House:
                if (index < this.houses.Length)
                {
                    this.houses[index].Paint(color);
                    return true;
                }

                break;

            case ObjectType.Paper:
                if (index < this.papers.Length)
                {
                    this.papers[index].Paint(color);
                    return true;
                }

                break;
        }

        return false;
    }

此外我想改变索引的含义。如果为零,则绘制该类型的所有对象,否则绘制列表[index - 1]。

    public bool Paint(ObjectType type, int index, System.Drawing.Color color)
    {
        switch (type)
        {
            case ObjectType.Car:
                if (index <= this.cars.Length)
                {
                    if (index != 0)
                    {
                        this.cars[index - 1].Paint(color);
                    }
                    else
                    {
                        foreach (var car in this.cars)
                        {
                            car.Paint(color);
                        }
                    }
                    return true;
                }

                break;

            case ObjectType.House:
                if (index <= this.houses.Length)
                {
                    if (index != 0)
                    {
                        this.houses[index - 1].Paint(color);
                    }
                    else
                    {
                        foreach (var house in this.houses)
                        {
                            house.Paint(color);
                        }
                    }
                    return true;
                }

                break;

            case ObjectType.Paper:
                if (index <= this.papers.Length)
                {
                    if (index != 0)
                    {
                        this.papers[index - 1].Paint(color);
                    }
                    else
                    {
                        foreach (var paper in this.papers)
                        {
                            paper.Paint(color);
                        }
                    }
                    return true;
                }

                break;
        }

        return false;
    }

你知道这会发生什么。我实际上有更多的类型和更多的方法。有没有办法在不使用IPaintable[][]的情况下封装不同数组的处理?

1 个答案:

答案 0 :(得分:2)

您只需要实现一个共同的接口。说IPaintable

public interface IPaintable
{
    void Paint(System.Drawing.Color color);
}

在所有这些类中实现它。

public class MyCar : IPaintable
{
    public void Paint(System.Drawing.Color color) { /* ... */ }
}

public class MyHouse : IPaintable
{
    public void Paint(Color color) { /* ... */ }
}

...

然后你可以改变Painter的Paint方法,如下所示

public bool Paint(IList<IPaintable> paintables, int index, Color color)
{
    if (index < paintables.Count)
    {
        paintables[index].Paint(color);
        return true;
    }

    return false;
}

而不是说要使用哪个数组,只需传递数组本身。

如果你发现自己在很多地方找到了要使用的阵列,你可以介绍一种方法,为你做到这一点。

private IList<IPaintable> GetPaintables(ObjectType type)
{
   switch (type)
    {
        case ObjectType.Car:
             return this.cars;
        case ObjectType.House:
             return this.houses;
        case ObjectType.Paper:
             return this.papers;
        default:
             throw new ArgumentOutOfRangeException();
    }
}

然后将其称为

Paint(GetPaintables(ObjectType.House), index, color);

请记住,在应用程序中每个枚举只有一个switch语句不是问题。问题是反复使用switch语句。因此GetPaintables本身并不是问题,如果恰好是您切换ObjectType的唯一地方。