Эффективная обработка одного и нескольких значений в методах C # - PullRequest
2 голосов
/ 02 марта 2009

У меня есть такой метод:

AverageAndDoSomeMath (Point2)

и мне интересно, как справиться:

AverageAndDoSomeMath (Point2) // single
AverageAndDoSomeMath (Point2 collection) // multiple

предпочтительно с использованием одной реализации.

Для сбора я планирую использовать тип IEnumerable, чтобы я мог передавать любой вид коллекции, но для одного значения я не хочу переносить и передавать его как коллекцию, потому что сама коллекция не имеет смысла, кроме как для удовлетворения типа.

Как лучше всего справиться с этим самым ясным, быстрым и эффективным способом?

РЕДАКТИРОВАТЬ: Может быть, я должен был выбрать лучшее имя метода, но метод вычисляет среднее значение всех точек, для 1 значения это не имеет смысла, но думаю, что это значение будет использоваться для расчета другое значение, но важно найти среднее, поэтому я не могу вызвать 1-й метод.

Ответы [ 3 ]

9 голосов
/ 02 марта 2009

Я знаю, что вы сказали, что не хотите оборачивать это и передавать как коллекцию, но есть два способа сделать это с минимальными хлопотами, поэтому я опубликую их на случай, если вы не знаете об этом .

Вы можете использовать params для вашего метода:

public void Average(params Point2[] points)

, после чего вы можете вызвать его с любым количеством аргументов или с массивом:

Average(P1);
Average(P2, P3, P4);
Average(); // this one becomes an empty array in the method

Point[] array = new Point[] { P1, P2, P3, P4 };
Average(array);

Или, альтернативно, вы можете использовать синтаксис короткого массива, чтобы обернуть ваш объект:

Average({ P1 }); // this is legal C# for making an array with 1 element

РЕДАКТИРОВАТЬ: После прочтения вашей заметки, я бы предположил, что массив params является самым ясным способом сделать то, что вы хотите. Единственный реальный недостаток в том, что вы не можете передать IEnumerable<Point2> (или другие коллекции, например List<Point2>) без первого вызова ToArray(), потому что он принимает только фактические массивы.

9 голосов
/ 02 марта 2009

Напишите двумя способами

  • AverageAndDoSomeMath (Point2 point)
  • AverageAndDoSomeMath (IEnumerable points)

и заставьте 1-го вызвать 2-го, завернув его в коллекцию.

public decimal AverageAndDoSomeMath (Point2 point)
{
    return AverageAndSomeMath(new []{point});
}

Полагаю, вы это уже имели в виду, но подумали, что это не правильное решение, верно?

Редактировать: Упрощенный метод (спасибо Фредди Риос)

1 голос
/ 02 марта 2009

одна ответственность за метод говорит, что ваш метод должен делать только одно - вычислять среднее арифметическое - и все. Нет "AndDoSomeOtherMath".

И если вы посмотрите на формулу для среднего значения, вы, безусловно, можете рассчитать что-то значимое только с одной точкой. Это стандартное отклонение, которое требует двух или более.

К вашему сведению, вы можете рассчитать среднее и стандартное отклонение на лету, не сохраняя все значения. Это намного проще в памяти. У Джона Д. Кука есть отличная статья в блоге о том, как сделать это для стандартного отклонения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...