I have a method that needs to allow a wide variety of input types. There are two categories of arguments: boundary type arguments, and actual data input arguments.
The boundary arguments are for example, order, frequency, number of points, and number of data points. These boundary arguments are of type int and are common, regardless of the actual data input argument type.
The actual input arguments may be of types: byte, int, short, uint, float, double, decimal, long, etc. To complicate matters further, the actual input data may be individual data, or a list or array of that type. So, the actual input may come as List or uint[], etc. This input is ultimately converted to type double - either as single data or double[].
The method consists of three parts: part one checks the validity of the boundary arguments. This part always applies regardles of the actual input data type. Part two checks and processes the input data arguments. This part changes depending of the type of the input data. Part three performs calculations on the data and is once again common.
I have thought about generic, and I have thought about standard overloading with generics but both seem inefficient. I have come up with what I believe is a workable solution but would appreciate comments: Is my approach computationally efficent, and is there a better way to do this. Your comments would be appreciated.
This is what I currently have:
// ... create lists to store data
static List<double> aList = new List<double>(8);
static List<double> fList = new List<double>(8);
public static double[] MyMethod(int numPts, int numData, object aValue, object fValue)
{
// ... part 1
if (numData < 2) throw new ArgumentOutOfRangeException("numberData must be >= 2.");
if (numPts < 2) throw new ArgumentOutOfRangeException("numberPoints must be >= 2.");
if (numData < numPts) throw new ArgumentOutOfRangeException("numberData must be
>= numPts.");
// ... part 2
if (aValue is byte || aValue is short || aValue is int || aValue is long ||
aValue is float || aValue is double || aValue is decimal ||
aValue is List<byte> || aValue is byte[] || aValue is List<short> ||
aValue is short[] || aValue is List<int> || aValue is int[] ||
aValue is List<float> || aValue is float[] || aValue is List<double> ||
aValue is double[])
{ }
else throw new ArgumentException("a values must be of a numeric type.");
double a = 0.0;
if (aValue is byte || aValue is short || aValue is int || aValue is long ||
aValue is float || aValue is double || aValue is decimal)
{
a = (double)aValue;
// ... store individual values
aList.Add(a);
// ... create the x variable vector
double[] x = aList.ToArray(); // a values
}
else if (aValue is List<byte> || aValue is List<short> || aValue is List<int> ||
aValue is List<float> || aValue is List<double>)
{
// ... get the runtime type of the aValue object
Type t = aValue.GetType();
// ... convert the aValue object to a generic list
IList tmp = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(t));
// ... convert the generic list to a strongly typed list
List<double> aValuesList = tmp.Cast<double>().ToList();
// ... create the x variable vector
double[] x = aValuesList.ToArray(); // a values
}
else
{
// ... process the vector input
// ... get the runtime type of the aValue object
Type t = aValue.GetType();
// ... convert the aValue object to an array
Array tmp = Array.CreateInstance(typeof([]).MakeGenericType(t), aValue.Length);
// ... convert the generic array to a strongly typed array
double[] x = tmp.Cast<double>().ToArray();
}
// ... part 3
{
// ... do calculations
}
}