Question

I have a method like:

AverageAndDoSomeMath (Point2)

and I wonder how to handle:

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

using a single implementation preferably.

For collection, I plan to use the IEnumerable type so I can pass any kind of collection, but for a single value, I don't want to wrap and pass it as a collection, because the collection itself serves no purpose, other than to satisfy the type.

How to best handle it in the clearest, fastest, most efficient way?

EDIT: Maybe I should have chosen a better method name, but the method calculates the average of all the points, for 1 value it doesn't make sense, but think of it as that the value will be used to say calculate another value, but what's important is finding the average, so I can't call the 1st method.

Was it helpful?

Solution

I know you said you didn't want to wrap it and pass it as a collection, but there are two ways you can do this with minimal hassle, so I'll post them in case you weren't aware of one.

You could use params on your method:

public void Average(params Point2[] points)

after which you can call it with any number of arguments, or with an array:

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

Or alternately, you can use short array syntax to wrap up your object:

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

EDIT: After reading your note, I would suggest that a params array is the clearest way to do what you want. The only real downside to it is that you can't pass in an IEnumerable<Point2> (or other collections like a List<Point2>) without first calling ToArray(), because it only takes actual arrays.

OTHER TIPS

Write two methods

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

and make the 1st one call the 2nd one by wrapping it in a collection.

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

I'm guessing that's what you already had in mind but thought it wasn't the correct solution, right?

Edit: Simplified the method (thanks to Freddy Rios)

a single responsibility per method would say your method should only do one thing - calculate the arithmetic mean - and that's it. No "AndDoSomeOtherMath".

And if you look at the formula for the mean, you can certainly calculate something meaningful with just one point. It's standard deviation that requires two or more.

FYI, you can calculate a mean and standard deviation on the fly without having to store all the values. It's a lot easier on memory. John D. Cook has a great blog article on how to do it for standard deviation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top