Поддерживать список <>, который содержит несколько классов T - PullRequest
1 голос
/ 09 августа 2011

Все мои классы являются производными от этого класса T:

public abstract class Problem<T, TResult> : IEquatable<T>
{
    protected Problem()
    {
        Results = new TResult[ResultCount];
    }

    protected Problem(int problemNumber, int subject, int seconds) : this()
    {
        this.ProblemNumber = problemNumber;
        this.Subject = subject;
        this.Seconds = seconds;
    }

    public int ProblemNumber { get; set; }
    public int Subject { get; set; }
    public int Seconds { get; set; }
    public abstract int ResultCount { get; }
    public TResult[] Results { get; set; }
    public abstract bool IsCorrect { get; }
    protected abstract bool CheckTheAnswer(params TResult[] results);
    public abstract bool Equals(T other);
}

Мне нужно иметь их список, но List запрашивает определенный тип данных для T и TResult.Ну, нет необходимости в списке.

Я бы не хотел использовать тип данных объекта для каждого приведения (потому что я все время использовал бы очень большой регистр переключателей).

ОБНОВЛЕНИЕ 1:

Это один из моих классов:

public class Comparison2 : Problem<Comparison2, Comparators>
{
    public Comparison2(decimal number1, decimal number2) : base()
    {
        this.SetNumbers(number1, number2);
    }

    public Comparison2(decimal number1, decimal number2, int problemNumber, int subject, int seconds)
        : base(problemNumber, subject, seconds)
    {
        this.SetNumbers(number1, number2);
    }

    private void SetNumbers(decimal number1, decimal number2)
    {
        this.Number1 = number1;
        this.Number2 = number2;
    }

    public decimal Number1
    {
        get;
        set;
    }

    public decimal Number2
    {
        get;
        set;
    }

    public override int ResultCount
    {
        get { return 1; }
    }

    public override bool IsCorrect
    {
        get { return this.CheckTheAnswer(Results[0]); }
    }

    protected override bool CheckTheAnswer(params Comparators[] results)
    {
        if (results.Length != ResultCount)
            throw new ArgumentException("Only expected " + ResultCount + " arguments.");

        Comparators result = results[0];

        switch (result)
        {
            case Comparators.Minor:
                return Number1 < Number2;
            case Comparators.Major:
                return Number1 > Number2;
            case Comparators.Equal:
                return Number1 == Number2;
            case Comparators.None:
                return false;
            default:
                throw new Exception("Comparator unexpected");
        }
    }

    public override bool Equals(Comparison2 other)
    {
        if (other == null)
            return false;

        return this.Number1 == other.Number1 && Number2 == other.Number2;
    }
}

Я планирую поместить их все в список <> и извлечь каждый их свойства напрямую.

Ответы [ 5 ]

1 голос
/ 13 августа 2011

Как уже говорилось в комментариях, сложно сказать, как улучшить свой дизайн без всей картины.Возможно, вам придется создать отдельный класс для каждого конкретного типа T, например IntegerProblem, FractionProblem и т. Д., Но я не уверен.

Часть вашего вопроса связана с большими операторами switch.В вашем обновлении у вас есть, возможно, ненужный оператор switch, поэтому я думаю, что если я объясню вам, как избавиться от таких переключателей, вы можете избежать многих из них в других местах.

Это считается плохой привычкой, если вывключить тип или состояние объекта.Обычно это означает, что какой-то другой объект слишком много знает (тесно связан) с этим объектом.Вместо того, чтобы спрашивать объект о его состоянии и действовать в соответствии с ответом, вы должны попросить сам объект действовать в зависимости от его собственного состояния.

Это происходит в вашем методе CheckTheAnswer.Экземпляр Comparison2 запрашивает экземпляр Comparators, каково его состояние, а затем выполняет некоторую работу в зависимости от него.Вместо этого вы должны попросить экземпляр Comparators проверить Number1 и Number2.Итак, вам нужно добавить абстрактный метод в класс Comparators (вы можете назвать его, например, «check»), который возвращает bool и принимает два десятичных аргумента.Затем создайте подклассы Comparators для каждого из состояний (например, MinorComparators, MajorComparators и NoneComparators) и переопределите в них абстрактный метод («check»), чтобы каждый подкласс возвращал тот же результат, что и ваш переключатель.

Таким образомвам не нужно писать большие ключи и вы можете добавлять новые типы компараторов, не меняя ни один из ваших подклассов задачи.

1 голос
/ 09 августа 2011
  1. Вы можете использовать object;
  2. Вы можете использовать ArrayList вместо List<T>;
  3. Вы можете создать общий интерфейс для обоих типов и использовать его в своем списке: List<ICommonInterface>
0 голосов
/ 09 августа 2011

У меня нет ответа, но я нашел грамматическое представление о том, как он должен отображаться в UML.Надеюсь, что эта помощь альтернативный текст http://www.forum -omondo.com / Documentation_eclipseuml_2008 / jdk15 / uml_editor_generic_type.png

0 голосов
/ 09 августа 2011

Вы должны использовать объект в качестве параметров типа для задачи. Компилятор не может творить чудеса ... если вы вставляете в Список различные типы элементов Problem, единственное, что объединяет эти элементы, это то, что они происходят от объекта

0 голосов
/ 09 августа 2011

Не уверен, что именно вам нужно делать с этими предметами, но шаблон Посетитель может вам помочь.

Шаблон посетителя позволяет вам просматривать список разнородных предметов очень удобным способом.

...