Эффективная обработка одного и нескольких значений в методах C#
Вопрос
У меня есть такой метод:
AverageAndDoSomeMath (Point2)
и мне интересно, как справиться:
AverageAndDoSomeMath (Point2) // single
AverageAndDoSomeMath (Point2 collection) // multiple
желательно использовать одну реализацию.
Для коллекции я планирую использовать тип IEnumerable, чтобы можно было передать любую коллекцию, но для одного значения я не хочу обертывать и передавать его как коллекцию, потому что сама коллекция не служит никакой другой цели, кроме как удовлетворить тип.
Как лучше всего справиться с этим самым ясным, быстрым и эффективным способом?
РЕДАКТИРОВАТЬ:Возможно, мне следовало выбрать лучшее имя метода, но метод вычисляет среднее значение всех точек, для 1 значения это не имеет смысла, но думайте об этом так, что значение будет использоваться для вычисления другого значения, но что важно найти среднее значение, поэтому я не могу вызвать первый метод.
Решение
Я знаю, вы сказали, что не хотите обертывать его и передавать как коллекцию, но есть два способа сделать это с минимальными хлопотами, поэтому я опубликую их, если вы об одном не знаете.
Вы можете использовать параметры в своем методе:
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
РЕДАКТИРОВАТЬ: Прочитав вашу заметку, я бы предположил, что массив параметров — это самый понятный способ сделать то, что вы хотите.Единственным реальным недостатком является то, что вы не можете пройти IEnumerable<Point2>
(или другие коллекции, такие как List<Point2>
) без предварительного звонка ToArray()
, потому что он принимает только реальные массивы.
Другие советы
Напишите два метода
- AverageAndDoSomeMath (балл Point2)
- AverageAndDoSomeMath (баллы IEnumerable<Point2>)
и заставьте первый вызвать второй, завернув его в коллекцию.
public decimal AverageAndDoSomeMath (Point2 point)
{
return AverageAndSomeMath(new []{point});
}
Я предполагаю, что вы уже имели в виду это, но подумали, что это неправильное решение, верно?
Редактировать: Упростил метод (спасибо Фредди Риосу)
единая ответственность за каждый метод будет означать, что ваш метод должен делать только одну вещь - вычислять среднее арифметическое - и все.Нет «AndDoSomeOtherMath».
И если вы посмотрите на формула Что касается среднего значения, вы, безусловно, можете вычислить что-то значимое, используя всего одну точку.Это стандартное отклонение, требующее двух или более.
К вашему сведению, вы можете рассчитать среднее и стандартное отклонение на лету, без необходимости сохранять все значения.Это намного легче для памяти.Джон Д.У Кука есть отличная статья в блоге о том, как это сделать для стандартного отклонения.