Overriding many functions of class at once with C# - c#

Maybe overriding isn't the correct term here.
I want to extend some of the System.Math class functions to work on double arrays.
What I'm currently doing is:
public double[] Sin(double[] d)
{
double[] result = new double[d.Length];
for(int i=0;i<result.Length;i++)
result[i] = Math.Sin(d[i]);
}
For many functions in a Math (about 20) just replacing Sin by Cos,Round,...
Is there a way to make this more elegant?
Please note that I'm building something to allow the user to evaluate expressions in runtime.
The user needs to be able to write "Cos(d)" for d double array and for all the functions, so solutions from the input side aren't really an option.
Thanks all

Not really, but you can shorten it with Array.ConvertAll:
double[] result = Array.ConvertAll(d, Math.Sin);
If the function name is in a string, you might be able to use a dictionary:
var dict = new Dictionary<string, Func<double[], double[]>> {
{ "Sin", a => Array.ConvertAll(a, Math.Sin) },
{ "Cos", a => Array.ConvertAll(a, Math.Cos) }
};
double[] d = { 1, 2 };
double[] result = dict["Sin"](d); // { 0.8414709848078965, 0.90929742682568171 }

You can create more generic method to work with the arrays. Something like this
internal static void Transform(double[] values, Func<double, double> transformation)
{
for(int i = 0; i < values.Length; i++)
values[i] = transformation[values[i]];
}
Now you can use more concrete methods like
internal static void Sin(doube[] values)
{
return Transform(values, Math.Sin);
}
Or
internal static void Cos(doube[] values)
{
return Transform(values, Math.Cos);
}
the the usage will be like this
var result = Sin(values)

You could use Extension methods:
public static class MathExtensions
{
public static double[] Sin(this double[] input)
{
return input.Select(Math.Sin).ToArray();
}
}
And then the call would be:
var f = d.Sin();
Note: This doesn't get the syntax you wanted, nor does it solve the issue of having to write one of these for each of the corresponding Math methods but I'll post it here as an answer to how to extend existing methods more elegantly.

Related

Passing the dimension of an Array as a Parameter in C#

I'm learning C# and am trying to implement a versatile RandomVar class along with some methods for computing common statistics as practice. I'd like to be able form the arbitrary Joint probability RandomVariable from its components by instantiating a new variable of dimension N where N is passed into the constructor. I'd like to implement random Var X as two one dimensional lists of doubles, and the randomVar XY not as two lists of length n^2, but as a randomVar of type double[][] which otherwise can still use all of the same methods (ExpectedValue, Covariance, etc).
I'm having a lot of trouble implementing this. Other than the first naive approach (which had lots of copy and pasting), I've tried inheriting from a base RandomVar class into a JointRandomVar class -- still a lot of copy-pasting. Now I'm trying to the probabilities and outcomes arrays of Class RandomVar as Generics of type List -- this however produces a lot of problems as I can't figure out how to write the methods in an adaptable way (The std_Dev method can't iterate over the way it needs to in general -- so I need some flexible way to define the method so that if the "dimension" of the random Var is 2, the std_Dev method will do a double loop, or flatten out the array for the process of iterating).
Wanting some design help from more experienced programmers -- is having the probabilities/outcomes arrays List the best way to pass a parameter like this?
Thank you very much for your assistance.
EDIT: Here is the the version of the code for all doubles, so people can read it since the un-updated version seemed more confusing to people. I'd like to be able to have all of these methods work on objects of type double[] for any dimension of array, and it to be possible to instantiate the class with _values and _probs having any dimension.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Chapter_3_GUI
{
class RandomVar
{
private double[] _values;
private double[] _probs;
private double _mean;
private double _stddev;
private int _length;
private double _evalue;
public RandomVar(double[] values, double[] probs)
{
_values = values;
_probs = probs;
_mean = meanCalc(_values);
_stddev = stddevCalc(_values, _mean);
_length = _values.Length;
_evalue = expectedVal(_probs, _values, _length);
}
public double[] Values
{
get { return _values; }
set { _values = value; }
}
public double Mean
{
get { return _mean; }
}
public double Stdev
{
get { return _stddev; }
}
public static double meanCalc(double[] var)
{
double mean = var.Sum();
return mean;
}
public static double stddevCalc(double[] var, double mean)
{
double[] varianceArr = new double[var.Length];
for (int i = 0; i <= var.Length; i++)
varianceArr[i] = (var[i] - mean) * (var[i] - mean);
double variance = varianceArr.Sum();
double stddev = Math.Sqrt(variance);
return stddev;
{
}
}
public static double[][] multiplyProbs(RandomVar X, RandomVar Y, double[][] cprobMatrix)
{
double[][] probArr = new double[X._length][Y._length];
for (int i=0; i <= probArr.Length; i++)
{
for (int j =0; j <= probArr.Length; j++)
{
probArr[i][j] = Y._probs[j] * cprobMatrix[i][j];
}
}
return probArr;
}
public static RandomVar multiplyVars(RandomVar X, RandomVar Y, Func<double,double> f)
{
double[][] productArr = new double[X._length][Y._length];
for (int i=0; i<= productArr.Length; i++)
{
for (int j=0; j <= productArr.Length; i=j++)
{
productArr[i][j] = f(X._values[i], Y._values[j]);
}
}
double[][] probArr = multiplyProbs(X, Y, cprobMatrix);
RandomVar product = new RandomVar(productArr, probArr);
return product;
}
public static double expectedVal(double[] _probs, double[] _values, int _length)
{
double[] expectedArr = new double[_length];
for (int i = 0; i <= expectedArr.Length; i++)
{
expectedArr[i] = _probs[i] * _values[i];
}
double evalue = expectedArr.Sum();
return evalue;
}
public static double covarianceCalc(RandomVar X, RandomVar Y, Func<double, double> f)
{
RandomVar VarXY = multiplyVars(X, Y, f);
double correlation = expectedVal(VarXY._probs, VarXY._values, VarXY._length);
double covariance = correlation - (X._mean * Y._mean);
return covariance;
}
}
}
Is the cardinality of each dimension going to be the same? Your comment about "treating it as one long array of size n^k" suggests it is. That is, n is the length of value/probability pairs in each dimension.
The other question I have is, what is the reasoning behind passing the values and probabilities in two different arrays? If it were me, I'd declare a struct that contains the pairs, e.g.:
struct ValueProbPair
{
public readonly double Value;
public readonly double Probability;
public ValueProbPair(double value, double probability)
{
Value = value;
Probability = probability;
}
}
Finally, as far as your specific question goes…well, it's not clear what the specific question is. You seem to have a broad question regarding a flexible way to implement this.
It seems to me that the biggest challenge here (i.e. the roadblock with the least intuitively obvious solution) is in the title of your question:
Passing the dimension of an Array as a Parameter
You can do this, i.e. create an appropriate array object, by using the Array.CreateInstance(Type, int[]) overload. IMHO, it will also work better if (but is not required that) you can consolidate the value/probability pairs into a single struct.
The other big caveat is that you won't get the benefit of compiler optimizations for accessing array elements. You'll have to use e.g. the GetValue() method, which will most likely prevent the compiler from accessing array elements directly (the optimization is theoretically possible, but seems unlikely to me).
So, for example, you could do something like:
Array Combine(ValueProbPair[] newDimension, Array previousDimensions)
{
int[] rankLengths = new int[previousDimensions.Rank + 1];
for (int j = 0; j < previousDimensions.Rank; j++)
{
rankLengths[j] = previousDimensions.GetLength(j);
}
rankLengths[previousDimensions.Rank] = newDimension.Length;
Array result = Array.CreateInstance(typeof(ValueProbPair), rankLengths);
// then fill in your matrix using GetValue and SetValue to
// access individual array elements...
// Finally, return the new multi-dimensional array:
return result;
}
The various array method overloads that access elements use params array parameters, so you can without too much difficulty write code that can handle matrices of arbitrary dimension. E.g.:
IEnumerable<double> GetAllValues(Array source)
{
int[] index = new int[source.Rank];
while (true)
{
yield return (double)source.GetValue(index);
int j = 0;
while (++index[j] == source.GetLength(j))
{
index[j] = 0;
if (++j == index.Length)
{
yield break;
}
}
}
}
One last note: for dealing with value/probability, depending on your scenario you might actually find it makes more sense to do all this using dictionaries. There are different complications, but the basic building block would be Dictionary<double, object>, where the value is either double or another Dictionary<double, object>. Then if you are looking for e.g. a combined probability, you don't have to scan lists of values, but rather can just look them up directly as the key in the dictionary.

Passing an IEnumerable of Numeric Values as a parameter to method

I'm playing around with a very simple program to take an array of doubles and return the standard deviation. This part worked but I wanted to make the code more reusable. I would like to make it so the method can accept a parameter of any type that could be considered numeric and return the standard deviation instead of hardcoding a double type (like I initially did in this program). How does one go about this and what is the proper term for it?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
double[] avg = { 3.4, 55.6, 10.0, 4.5, 2, 2 };
double x = avg.Average();
//first round of testing
Console.WriteLine("The average of the first array is below ");
Console.WriteLine(x);
Console.WriteLine("below should be the standard deviation!");
Console.WriteLine(CalculateStandardDeviation(avg));
Console.ReadLine();
int[] intAvg = { 4, 3, 5, 6, 2 };
double secondAvg = intAvg.Average();
Console.WriteLine("The average of the second array is below ");
Console.WriteLine(secondAvg);
//this is where the error is happening
//CalculateStandardDeviation(secondAvg);
}
//this is where I tried to make the query more reusable
public static double CalculateStandardDeviation(IEnumerable<double> values)
{
double avg = values.Average();
double sum = 0;
foreach (double d in values)
{
sum += Math.Pow((d - avg), 2);
}
return Math.Pow(sum / (values.Count() - 1),.5);
}
}
}
You could use something like this:
public static decimal CalculateStandardDeviation<T>(IEnumerable<T> values)
{
IEnumerable<decimal> decimalValues = values.Select(v => Convert.ToDecimal(v));
decimal result = 0;
// calculate standard deviation on decimalValues
return result;
}
It will throw an exception if values contains values that can't be converted to a decimal, but will work if the values are of an appropriate type, and I think that makes perfect sense.
Unfortunately, there is no base class for all numbers. You can do this with a generic run-time checking method, or a compile-time safe set of overloads.
Generic Method:
public static T CalculateStandardDeviation(IEnumerable<T> values)
{
var valueArray = values.Select(Convert.ToDecimal).ToArray();
//...
return (T)standardDeviation;
}
The problem with using a single generic method is that you can't put a type constraint on the type parameter that would restrict it to only numeric types. You would have to resort to failing at run-time. There would be nothing to stop you from calling the method with an array of strings, or objects, or Colors, or HttpWebRequests, etc. and unless you do in fact know how to calculate the standard deviation of a color, you should probably stick to individual overrides for a particular numeric type:
I would recommend using the decimal type as your main implementation, and then casting everything to it.
Type-Specific Overloads:
public static decimal CalculateStandardDeviation(IEnumerable<decimal> values)
{
//...
}
public static double CalculateStandardDeviation(IEnumerable<double> values)
{
return (double)CalculateStandardDeviation(values.Select(Convert.ToDecimal));
}
public static int CalculateStandardDeviation(IEnumerable<int> values)
{
return (int)CalculateStandardDeviation(values.Select(Convert.ToDecimal));
}
// etc...
Use C# Generics.
Your function signature will be:
public static T CalculateStandardDeviation(IEnumerable<T> values)
And you can use it like:
int stdDev = CalculateStandardDeviation([int-array]);
double stdDev = CalculateStandardDeviation([double-array]);
Please follow this link:
http://msdn.microsoft.com/en-us/library/ms379564%28VS.80%29.aspx
Edit:
To resolve the Average issue on the generic types, please take a look in this library:
How to Implement Generic Method to do Math calculations on different value types
Obs: Suggestion from Brian.
EDIT
You should use JLRishe's answer, it's much more elegant than this.
You should probably start by adding generics to your method and use the type converter to transform your unknown input into doubles like so :
public static double CalculateStandardDeviation<TSource>(IEnumerable<TSource> inputs)
{
var converter = TypeDescriptor.GetConverter(typeof (double));
if (!converter.CanConvertFrom(typeof(TSource)))
return 0;
var values = new List<double>();
foreach (var value in inputs)
{
values.Add((double) converter.ConvertFrom(value));
}
// Your logic here ...
return ...;
}
I did not tested this snippet but you get the idea.
Foreword:
this answer builds on
How to verify whether a type overloads/supports a certain operator?
and
http://www.codeproject.com/Articles/87438/TinyLisp-A-Language-and-Parser-to-See-LINQ-Express
The second link shows how to compile and evaluate linq expressions.
In short you could forego static type safety and check for the ability of a type to support specific operations at runtime (first link), in case it does not you could throw an exception as the following sample demonstrates:
void Main()
{
DoAdd<float>(5,6);
DoAdd<int>(5,6);
DoAdd<bool>(true,false);
}
// Define other methods and classes here
static void DoAdd<T>(T in1, T in2){
if(!HasAdd<T>()){throw new Exception("Unsupported Type!");}
var c1 = Expression.Constant(in1, typeof(T));
var c2 = Expression.Constant(in2, typeof(T));
var expression=Expression.Add(c1, c2);
Expression<Func<T>> lExpression = Expression.Lambda<Func<T>>(expression);
Func<T> fExpression = lExpression.Compile();
Console.WriteLine(fExpression());
}
static bool HasAdd<T>() {
var c = Expression.Constant(default(T), typeof(T));
try {
Expression.Add(c, c); // Throws an exception if + is not defined
return true;
} catch {
return false;
}
}
Passing an IEnumerable of Numeric Values as a parameter to method will be supported in C# 6.0

Closures and java anonymous inner classes

Would anyone be so kind to post the equivalent Java code for a closure like this one (obtained using C#) with anonymous inner classes?
public static Func<int, int> IncrementByN()
{
int n = 0; // n is local to the method
Func<int, int> increment = delegate(int x)
{
n++;
return x + n;
};
return increment;
}
static void Main(string[] args)
{
var v = IncrementByN();
Console.WriteLine(v(5)); // output 6
Console.WriteLine(v(6)); // output 8
}
Furthermore, can anyone explain how partial applications can be obtained if lexical closures are available and viceversa? For this second question, C# would be appreciated but it's your choice.
Thanks so much.
There is no closure yet in Java. Lambda expressions are coming in java 8. However, the only issue with what you're trying to translate is that it has state, which not something that lamba expressions will support i don't think. Keep in mind, it's really just a shorthand so that you can easily implement single method interfaces. You can however still simulate this I believe:
final AtomicInteger n = new AtomicInteger(0);
IncrementByN v = (int x) -> x + n.incrementAndGet();
System.out.println(v.increment(5));
System.out.println(v.increment(6));
I have not tested this code though, it's just meant as an example of what might possibly work in java 8.
Think of the collections api. Let's say they have this interface:
public interface CollectionMapper<S,T> {
public T map(S source);
}
And a method on java.util.Collection:
public interface Collection<K> {
public <T> Collection<T> map(CollectionMapper<K,T> mapper);
}
Now, let's see that without closures:
Collection<Long> mapped = coll.map(new CollectionMapper<Foo,Long>() {
public Long map(Foo foo) {
return foo.getLong();
}
}
Why not just write this:
Collection<Long> mapped = ...;
for (Foo foo : coll) {
mapped.add(foo.getLong());
}
Much more concise right?
Now introduce lambdas:
Collection<Long> mapped = coll.map( (Foo foo) -> foo.getLong() );
See how much nicer the syntax is? And you can chain it too (we'll assume there's an interface to do filtering which which returns boolean values to determine whether to filter out a value or not):
Collection<Long> mappedAndFiltered =
coll.map( (Foo foo) -> foo.getLong() )
.filter( (Long val) -> val.longValue() < 1000L );
This code is equivalent I believe (at least it produces the desired output):
public class Test {
static interface IncrementByN {
int increment(int x);
}
public static void main(String[] args) throws InterruptedException {
IncrementByN v = new IncrementByN() { //anonymous class
int n = 0;
#Override
public int increment(int x) {
n++;
return x + n;
}
};
System.out.println(v.increment(5)); // output 6
System.out.println(v.increment(6)); // output 8
}
}
Assuming we have a generic function interface:
public interface Func<A, B> {
B call A();
}
Then we can write it like this:
public class IncrementByN {
public static Func<Integer, Integer> IncrementByN()
{
final int n_outer = 0; // n is local to the method
Func<Integer, Integer> increment = new Func<Integer, Integer>() {
int n = n_outer; // capture it into a non-final instance variable
// we can really just write int n = 0; here
public Integer call(Integer x) {
n++;
return x + n;
}
};
return increment;
}
public static void main(String[] args) {
Func<Integer, Integer> v = IncrementByN();
System.out.println(v.call(5)); // output 6
System.out.println(v.call(6)); // output 8
}
}
Some notes:
In your program, you capture the variable n by reference from the enclosing scope, and can modify that variable from the closure. In Java, you can only capture final variables (thus capture is only by value).
What I did here is capture the final variable from the outside, and then assign it into a non-final instance variable inside the anonymous class. This allows "passing info" into the closure and at the same time having it be assignable inside the closure. However, this information flow only works "one way" -- changes to n inside the closure is not reflected in the enclosing scope. This is appropriate for this example because that local variable in the method is not used again after being captured by the closure.
If, instead, you want to be able to pass information "both ways", i.e. have the closure also be able to change things in the enclosing scope, and vice versa, you will need to instead capture a mutable data structure, like an array, and then make changes to elements inside that. That is uglier, and is rarer to need to do.

How do I create an IComparer for a Nunit CollectionAssert test?

I wish to create the following test in NUnit for the following scenario: we wish to test the a new calculation method being created yields results similar to that of an old system. An acceptable difference (or rather a redefinition of equality) between all values has been defined as
abs(old_val - new_val) < 0.0001
I know that I can loop through every value from the new list and compare to values from the old list and test the above condition.
How would achieve this using Nunit's CollectionAssert.AreEqual method (or some CollectionAssert method)?
The current answers are outdated. Since NUnit 2.5, there is an overload of CollectionAssert.AreEqual that takes a System.Collections.IComparer.
Here is a minimal implementation:
public class Comparer : System.Collections.IComparer
{
private readonly double _epsilon;
public Comparer(double epsilon)
{
_epsilon = epsilon;
}
public int Compare(object x, object y)
{
var a = (double)x;
var b = (double)y;
double delta = System.Math.Abs(a - b);
if (delta < _epsilon)
{
return 0;
}
return a.CompareTo(b);
}
}
[NUnit.Framework.Test]
public void MyTest()
{
var a = ...
var b = ...
NUnit.Framework.CollectionAssert.AreEqual(a, b, new Comparer(0.0001));
}
Well there is method from the NUnit Framework that allows me to do tolerance checks on collections. Refer to the Equal Constraint. One uses the AsCollection and Within extension methods. On that note though I am not 100% sure regarding the implications of this statement made
If you want to treat the arrays being compared as simple collections,
use the AsCollection modifier, which causes the comparison to be made
element by element, without regard for the rank or dimensions of the
array.
[Test]
//[ExpectedException()]
public void CheckLists_FailsAt0()
{
var expected = new[] { 0.0001, 0.4353245, 1.3455234, 345345.098098 };
var result1 = new[] { -0.0004, 0.43520, 1.3454, 345345.0980 };
Assert.That(result1, Is.EqualTo(expected).AsCollection.Within(0.0001), "fail at [0]"); // fail on [0]
}
[Test]
//[ExpectedException()]
public void CheckLists_FailAt1()
{
var expected = new[] { 0.0001, 0.4353245, 1.3455234, 345345.098098 };
var result1a = new[] { 0.0001000000 , 0.4348245000 , 1.3450234000 , 345345.0975980000 };
Assert.That(result1a, Is.EqualTo(expected).AsCollection.Within(0.0001), "fail at [1]"); // fail on [3]
}
[Test]
public void CheckLists_AllPass_ForNegativeDiff_of_1over10001()
{
var expected = new[] { 0.0001, 0.4353245, 1.3455234, 345345.098098 };
var result2 = new[] { 0.00009900 , 0.43532350 , 1.34552240 , 345345.09809700 };
Assert.That(result2, Is.EqualTo(expected).AsCollection.Within(0.0001)); // pass
}
[Test]
public void CheckLists_StillPass_ForPositiveDiff_of_1over10001()
{
var expected = new[] { 0.0001, 0.4353245, 1.3455234, 345345.098098 };
var result3 = new[] { 0.00010100 , 0.43532550 , 1.34552440 , 345345.09809900 };
Assert.That(result3, Is.EqualTo(expected).AsCollection.Within(0.0001)); // pass
}
NUnit does not define any delegate object or interface to perform custom checks to lists, and determine that a expected result is valid.
But I think that the best and simplest option is writing a small static method that achieve your checks:
private const float MIN_ACCEPT_VALUE = 0.0001f;
public static void IsAcceptableDifference(IList collection, IList oldCollection)
{
if (collection == null)
throw new Exception("Source collection is null");
if (oldCollection == null)
throw new Exception("Old collection is null");
if (collection.Count != oldCollection.Count)
throw new Exception("Different lenghts");
for (int i = 0; i < collection.Count; i++)
{
float newValue = (float)collection[i];
float oldValue = (float)oldCollection[i];
float difference = Math.Abs(oldValue - newValue);
if (difference < MIN_ACCEPT_VALUE)
{
throw new Exception(
string.Format(
"Found a difference of {0} at index {1}",
difference,
i));
}
}
}
You've asked how to achieve your desired test using a CollectionAssert method without looping through the list. I'm sure this is obvious, but looping is exactly what such a method would do...
The short answer to your exact question is that you can't use CollectionAssert methods to do what you want. However, if what you really want is an easy way to compare lists of floating point numbers and assert their equality, then read on.
The method Assert.AreEqual( double expected, double actual, double tolerance ) releases you from the need to write the individual item assertions yourself. Using LINQ, you could do something like this:
double delta = 0.0001;
IEnumerable<double> expectedValues;
IEnumerable<double> actualValues;
// code code code
foreach (var pair in expectedValues.Zip(actualValues, Tuple.Create))
{
Assert.AreEqual(pair.Item1, pair.Item2, delta, "Collections differ.");
}
If you wanted to get fancier, you could pull this out into a method of its own, catch the AssertionException, massage it and rethrow it for a cleaner interface.
If you don't care about which items differ:
var areEqual = expectedValues
.Zip(actualValues, Tuple.Create)
.Select(tup => Math.Abs(tup.Item1 - tup.Item2) < delta)
.All(b => b);
Assert.IsTrue(areEqual, "Collections differ.");

C# Dynamic Instantiation

I am in need of some help here about doing a dynamic instantiation in C#. What I want to accomplish is to be able to use a string variable that is used as the name in the instantiation. I think you can use reflection or something, but I am lost on this one. Here is my test code snippet and hopefully someone has an answer.
Averages is tied to a class that handles everything. So lets say I wanted to make test the variable and everything that is tied to the string of test could be passed as the instantiation. How could I create an object that can handle the variable test coming in, compile and be used in runtime? I know this may sound out of the ordinary, but instead of me using many IF's with multiple declarations of doubles. I could use a dynamic instantiation. Anyone that can help out I would be most appreciative.
Averages test = new Averages();
double[] testresult;
testresult = test.sma();
womp,,,I want to dynamically declare arrays of doubles. I already know how to declare a static array. What I am trying to accomplish is eliminating declaring 30 arrays that bascially do the same thing over and over again with a different naming.
So instead of doing this:
if (UITAName == "SMA")
{
Averages sma = new Averages();
double[] smaresult;
smaresult = sma.sma(UITAName, YVal, UITPeriod, UITShift);
chart1.Series[UITA].Points.DataBindXY(test2, test1);
}
if (UITAName == "TMA")
{
Averages tma = new Averages();
double[] tmaresult;
tmaresult = tma.tma(UITAName, YVal, UITPeriod);
chart1.Series[UITA].Points.DataBindXY(XVal, tmaresult);
}
else
if (UITAName == "EMA")
{
Averages ema = new Averages();
double[] emaresult;
emaresult = ema.ema(UITAName, YVal, UITPeriod);
chart1.Series[UITA].Points.DataBindXY(XVal, emaresult);
}
I want to do this only once for everything instead of doing IF statements. The problem is that you cannot compile with a declaration of a string. There has to be a way I just do not know how.
Averages UITAName = new Averages();
double[] UITANameresult;
UITANameresult = UITAName.UITAName(UITAName, YVal, UITPeriod);
chart1.Series[UITA].Points.DataBindXY(XVal, UITANameresult);
You can instantiate a class dynamically using Reflection, with Activator.CreateInstance.
Activator.CreateInstance("MyAssembly", "MyType");
However I'm not entirely clear on what you're trying to do. If you already have a class called Averages, what do you need dynamically instantiated? And I'm a bit worried by what you mean that it's "tied to a class that handles everything"...
Sounds like you might need to check out Func<> ??? Just my initial assessment without seeing a little more code to give me a clearer context.
To clarify, if you are wanting to pass the values as an argument, like you would on your command line, then you would need to instance the assembly. Otherwise, with Func<T, TResult> you can pass parameters dynamically to a method and get the return value.
Okay...if I get what you are saying...you want something that would resemble:
class Average
{
public double[] sma()
{
// do something
return dArray;
}
public double[] ema()
{
// do something
return dArray;
}
}
that is...the function 'name' would be the value of the string returned from a database query of some sort?
...and if that is the case then I don't know why you wouldn't just do a dictionary like:
Dictionary<string, double[]> testResults = new Dictionary<string, double[]>();
void GetDoubles(string name, params double[] args)
{
testResult[s] = GetAverages(args);
}
I think this could help you.
If i understand you correctly, you have method initinialization values in db as SMA,EMA,etc and you need to invoke the method at runtime,
string invokeMethod = GetValueFromDB() //ur logic to get the SMA or EMA or TMA from db
Type urType=typeof("yourclassname");
object unKnownObj = Activator.CreateInstance(urType);
//Fill your paramters to ur method(SMA,EMA) here
//ie, sma.sma(UITAName, YVal, UITPeriod, UITShift);
object[] paramValue = new object[4];
paramValue[0] = UITAName;
paramValue[1] = YVal;
paramValue[2] = UITPeriod;
paramValue[3] = UITShift;
object result=null;
try
{
result = urType.InvokeMember(invokeMethod, System.Reflection.BindingFlags.InvokeMethod, null, unKnownObj, paramValue);
}
catch (Exception ex)
{
//Ex handler
}
So this way you can avoid the multiple if loops and will invoke the method directly by the given name..
I think reflection might not be the best solution for your situation. Maybe decomposing your code a little bit might help, something along the following lines...
public interface ICalculation
{
double [] Calculate(double y, double period, double shift);
double XVal {get;}
}
public class SMA : ICalculation
{
public override double[] Calculate( double y, double period, double shift )
{
// do calculation, setting xval along the way
}
// more code
}
public class EMA : ICalculation
{
public override double[] Calculate( double y, double period, double shift )
{
// do calculation, setting xval along the way
}
// more code
}
public class Averages
{
public void HandleCalculation( ICalculation calc, double y, double p, double s )
{
double[] result = calc.Calculate( y, p, s );
chart.Series[UITA].Points.DataBindXY( calc.XVal, result );
}
}

Categories