Does C# support multiple return values? - c#

This is a very basic question, and if what I am thinking of doing is complicated/involved, then I don't expect you to go into detail... I've read that this may involve structs or hash or some other scary procedure I've not gotten to yet. If so, I'm sure it'll get me soon.
Working on learning classes, methods, and return values.
I'd like to have my class/method return Current Hour and Minute. Simple enough, really.
Is this constructed correctly, or properly?
class MyClass
{
public int GetHour (int hr, int min)
{
DateTime dt = DateTime.Now;
int hour = dt.Hour;
int minute = dt.Minute;
return hour;
return minute;
}
}
And, calling it from Main(): Getting some errors (No overload for method and Unreachable code detected)
static void Main ( string[] args )
{
MyClass mc = new MyClass ();
Console.WriteLine ("Hour: {0} \n Minute: {1}", mc.GetHour());
Console.ReadLine ();
}
Question is: Am I Close?

As mentioned by #ChaosPandion, in that specific case you would return a DateTime struct.
In general, however, you would have the following options:
Using out parameters
This is a simple way that will usually always work. However, it is a bit clunky, as the result is returned where you usually would expect the function arguments to be passed and the method signature might get lengthy and hard to refactor.
public void GetTime(out int hr, out int min)
{
DateTime dt = DateTime.Now;
hr = dt.Hour;
min = dt.Minute;
}
static void Main(string[] args)
{
// declare variables for out parameters first
int hour, minute;
GetTime(out hour, out minute);
}
Using an array
This is a simple method that works well if the values to be returned have the same type.
public int[] GetTime()
{
DateTime dt = DateTime.Now;
return new[] { dt.Hour, dt.Minute};
}
Using a property bag (A property bag is a simple class which only has properties)
This is very convenient and allows easy modification of the type and number of returned values later on without changing the method signature.
class A
{
int Prop1 { get; set; }
int Prop2 { get; set; }
}
public A SomeMethod()
{
return new A() { Prop1 = 1, Prop2 = 2 }
}
Using a Tuple
In C# 4.0 (requires VS 2010) you can use the Tuple<T1, T2, ...> class:
public Tuple<int, int> GetTime()
{
DateTime dt = DateTime.Now;
return Tuple.Create(dt.Hour, dt.Minute);
}
C# 7.0 Tuples
C# 7.0 adds support for multiple return values. You can write code like this to return an implicitly created tuple:
(string, string, string) LookupName(long id) // tuple return type
{
... // retrieve first, middle and last from data storage
return (first, middle, last); // tuple literal
}
The tuple elements are names Item1, Item2, etc by default, but you can also specify names, e.g.
(string first, string middle, string last) LookupName(long id) // tuple return type
{
... // retrieve first, middle and last from data storage
return (first, middle, last); // tuple literal
}
and then access the tuple elements via those names:
var names = LookupName(id);
WriteLine($"found {names.first} {names.last}.");

C# does not support multiple return values so in this case you should return a DateTime struct which is the idiomatic approach. The client code can simply ignore the properties that they don't care about. You could create your own simple struct but it really isn't worth the effort.

C# doesn't support the idea of directly returning multiple values from a method in that fashion. However there are a couple of ways to create methods which return multiple values. The first is to use ref / out parameters.
public void GetHourMinute(out int hour, out int minute) {
var now = DateTime.Now;
hour = now.Hour;
minute = now.Minute;
}
The second is to create a wrapper type which encapsulates the two values. Starting in 4.0 this can be made a bit easier by using the Tuple type.
public Tuple<int,int> GetHourMinute() {
var now = DateTime.Now;
return Tuple.Create(now.Hour, now.Minute);
}

I suggest you return the DateTime object. Then in your main method you call Hour and Minute properties.

1: You can't have two returns. Once the compiler reaches the return statement, the operation of the method is finished.
2: Why would you want your method to receive parameters if you don't use them? DateTime.Now gives you the current time, if you'll think of yourself as that method - what do you need in order to complete your task? Nothing.
So, practical tips:
1. Actually, the DateTime does what you need better than your method.
Console.WriteLine ("Hour: {0} \n Minute: {1}", DateTime.Now.Hour,DateTime.Now.Minute);
Would have been better,
but let's ignore that and consider it an exercise in classes.
2 Returning two values is against the concept of a method - a method returns one thing (there are exceptions as out ref, but we'll ignore them).
You can actually see that in your own code - your method name is GetHour not GetHourAndMinutes. I don't think I've ever seen a method's name with the word "and" - a method does only one thing.

Yeah, you can only return one 'thing' from method in C#.
The other problem you have is you are calling a method without any parameters. The things in the brackets:
public int GetHour (int hr, int min) // here
{
}
Are parameters. And you need to specify them when calling the method, like so:
mc.GetHour(1, 2);
But of course, in your case, it doesn't make sense to do this.
To answer the general question of: "How do I return more than one thing?" You encapsulate it in a class, set the properties, and return that class. It so happens, in the example you've given, the DateTime class does just that.
Hope this is helpful.

You cant return multiple value. TimeSpan is exactly what you are looking for. Create an object of that with hour, minute and even second that you want to capture and return it.
Come to think about it, for what you need above, you dont even have to write the method above. Just use DateTime.Now.TimeOfDay directly in your code

Sorry, you can't do that. You'd be better served returning an array or an object. You could return the DateTime object and use it.
Also as stated, your function signature wasn't being called properly.
class MyClass
{
public int[] GetHour ()
{
DateTime dt = DateTime.Now;
int hour = dt.Hour;
int minute = dt.Minute;
return new int[]{hour, minute};
}
}
static void Main ( string[] args )
{
MyClass mc = new MyClass ();
int[] temp = mc.GetHour();
Console.WriteLine ("Hour: {0} \n Minute: {1}", temp[0], temp[1]);
Console.ReadLine ();
}

In C# a method can return multiple times, if you use yield return format.
using System.Collections.Generic;
namespace YieldReturn
{
class Program
{
public static void Main(string[] args)
{
MyClass mc = new MyClass();
IEnumerator<int> enu = mc.GetHour().GetEnumerator();
enu.MoveNext();
int hour = enu.Current;
enu.MoveNext();
int min = enu.Current;
Console.WriteLine("Hour {0} min {1}", hour, min);
Console.ReadKey(true);
}
}
class MyClass
{
DateTime dt;
public MyClass()
{
dt = DateTime.Now;
}
public IEnumerable<int> GetHour()
{
int hour = dt.Hour;
int minute = dt.Minute;
yield return hour;
yield return minute;
}
}
}
Gives "Hour 8 min 50"

You can't return twice, only once.
Several return values at once require lambda expressions, and AFAIK, only Python is capable of that.
Syntax there goes like this:
return x, y
So maybe you should try IronPython, and then decompile to C#.
In C#, there are exactly two ways to return more than one value:
1. Use arguments as call by reference, that way you can assign 3 variables and then return.
2. Use some kind of struct/class/array/tuple/vector and place your multiple values into it.
Call by reference is something like this:
public static void xxx(ref var1, ref
var2, ref var3) {
var1 = 123;
var2 = 456;
var3 = 789;
return; }
then you do:
int a =1;
int b=2;
int c=3;
xxx(ref a, ref b, ref c);
Console.WriteLine(a.ToString());
Console.WriteLine(b.ToString());
Console.WriteLine(c.ToString());

The question I would like to ask you is why do you want to return multiple values? Returning multiple values for me means having multiple responsibilities in the function and that should be a big don't since it is violating SRP. But, if those return values are related maybe they make an object that you're missing and should be created instead? Or a list with one type of object.
So for short. Why? Encapsulate your return values in ONE object? Don't do multiple things in one function.
EDIT: In your case I wouldn't even wrap your functionality in a function just write:
static void Main ( string[] args )
{
MyClass mc = new MyClass ();
DateTime now = DateTime.Now;
int hour = now.Hour;
int min = now.Minute;
Console.WriteLine ("Hour: {0} \n Minute: {1}", hour, min);
Console.ReadLine ();
}
And your function name GetHour doesn't do what the function says... if it says GetHour it should return the hour and not the hour plus the minute.

Related

confused about return methods and voids in C#

Want feedback if i`m correct here?
Use void if you are not returning anything in a method,
otherwise
Name your data types used in the method criteria before method name.
use Return in the method before the calculation or output.
So something like this.
static int MyMethod(int x)
{
return 5 + x;
}
static void Main(string[] args)
{
Console.WriteLine(MyMethod(3));
}
// Outputs 8 (5 + 3)
What if my method has ints and doubles?
Do I write as follows? (another words do I have to mention every type i`m using prior to the method name?
static int double myMethod (int x, double y)
Even with that I dont know when is a method void? It seems my methods all return values.
Isnt the following returning the values of the arguments? So why should I label it void?
static void MyMethod(string fname, int age)
{
Console.WriteLine(fname + " is " + age);
}
static void Main(string[] args)
{
MyMethod("Liam", 20);
MyMethod("Jenny", 25);
MyMethod("Tom", 31);
}
I can only think that a void means there is no new calculation being done in the actual method body, passing arguments into a method and spitting them out for user viewing does not mean its "returning a value", I dont know what i`m talking about.
Let's be completely clear about what these bullets mean.
Use void if you are not returning anything in a method, otherwise
In this context, "return" means that the method provides an output that can be assigned to a variable by the caller. For example
int Return10()
{
return 10;
}
...allows the caller to do this:
int x = Return10();
Console.WriteLine(x); //Outputs "10"
A method should "return" void when its results cannot be assigned. For example, if the results are printed on the screen.
void Print10()
{
Console.WriteLine("10"); //Prints 10 to the screen
}
...which allows the caller to do this:
Print10();
You cannot assign it because it doesn't return anything. This doesn't work:
int x = Print10(); //Compiler error
Name your data types used in the method criteria before method name.
A method can return exactly one value or object. So "types" here is wrong. You can only specify one type.
Use return in the method before the calculation or output.
This is a little misleading. The return keyword should be followed by an expression which can be assigned.
int Return10()
{
return 10 + 10; //Is okay because it's an expression and could be assigned
}
int Return10()
{
var x = 10 + 10;
return x; //This is also okay; in fact it does exactly the same thing as the previous example
}
int Return10()
{
return Console.WriteLine("10"); //Compiler error; can't be assigned to anything.
}
By the way, a method can also output something and return it:
int WriteAndReturn10()
{
int x = 10;
Console.WriteLine(x);
return x;
}
I am going to address the following
What if my method has ints and doubles? Do I write as follows?
(another words do I have to mention every type i`m using prior to the
method name?
There are no built in ways or syntax to return more than one type from a method as the return parameter.. This is basically historical and has been this way since dinosaurs roamed the earth.
However, there are lots of options that achieve the same result. For instance, you could use a custom struct, you could use out parameters, you could use a class, or a delegate parameter of some kind. However, a modern succinct approach might be to use a Value Tuple:
static (int someInt, double someDouble) myMethod (int x, double y)
{
return (x,y);
}
Fun Fact : even though this looks like you a returning more than one type, you are actually just invoking a special syntax that wraps your return parameters in a single type of struct
Usage
var result = myMethod(1,2.2);
Console.WriteLine(result.someInt);
Console.WriteLine(result.someDouble);
Or if you want to get fancy, you can use the newer deconstructed syntax
var (someInt, someDouble) = myMethod(1,2.2);
Console.WriteLine(someInt);
Console.WriteLine(someDouble);
Additional Resources
return (C# Reference)
Methods (C# Programming Guide)
Tuple types (C# reference)
out parameter modifier (C# Reference)
ref (C# Reference)
Using Delegates (C# Programming Guide)

Inline use of function returning more than one value in C#

I am used to using functions that return a single value "in-line" like so:
Label1.Text = firstString + functionReturnSecondString(aGivenParameter);
Can this be done for a function that returns two values?
Hypothetical example:
label1.Text = multipleReturnFunction(parameter).firstValue
I have been looking into returning more than one value and it looks like the best options are using a tuple, struct, or an array list.
I made a working function that retuns a struct. However the way I got it to work I need to first call the function, then I can use the values. It doesn't seem possible to make it happen all on the same line without writing another function.
multipleReturnFunction(parameter);
Label1.Text = firstString + classOfStruct.secondString;
I haven't made a function that returns a tuple or array list yet, so I'm not sure. Is it possible to call those functions and reference the return values "inline"?
I appreciate your feedback.
I have a grotty hack for exactly this type of scenario - when you want to perform multiple operations on the return value without defining an extra variable to store it:
public static TResult Apply<TInput, TResult>(this TInput input, Func<TInput, TResult> transformation)
{
return transformation(input);
}
... and here's the reason it came about in the first place:
var collection = Enumerable.Range(1, 3);
// Average reimplemented with Aggregate.
double average = collection
.Aggregate(
new { Count = 0, Sum = 0 },
(acc, i) => new { Count = acc.Count + 1, Sum = acc.Sum + i })
.Apply(a => (double)a.Sum / (double)a.Count); // Note: we have access to both Sum and Count despite never having stored the result of the call to .Aggregate().
Console.WriteLine("Average: {0}", average);
Needless to say this is better suited for academic exercises than actual production code.
Alternatively, use the ref or they out keyword.
Example:
int a = 0, b = 0;
void DoSomething(ref int a, ref int b) {
a = 1;
b = 2;
}
Console.WriteLine(a); // Prints 1
Console.WriteLine(b); // Prints 2
It's not inline and I personally would consider a class or a struct before using the ref or the out keyword. Let's consider the theory: when you want to return multiple things, you have in fact an object that has multiple properties which you want to make available to the caller of your function.
Therefore it is much more correct to actually create an object (either by using a class or a struct) that represents what you want to make available and returning that.
The only time I use the ref or the out keyword is when using DLL imports because those functions often have pointers as their calling arguments and I personally don't see any benefit in using them in your typical normal application.
To do this inline, I think you would have to have another method that takes your struct and gives you the string you are looking for.
public string NewMethod(object yourStruct)
{
return string.Format("{0} {1}", yourStruct.value1, yourStruct.value2);
}
Then in the page, you do this:
Label1.Text = NewMethod(multipleReturnFunction(parameter));
C# doesn't have Inline functions, but it does support anonymous functions which can be closures.
With these techniques, you can say:
var firstString=default(String);
var secondString=default(String);
((Action<String>)(arg => {
firstString="abc"+arg;
secondString="xyz";
}))("wtf");
label1.Text=firstString+secondString;
Debug.Print("{0}", label1.Text);
((Action<String>)(arg => {
firstString="123"+arg;
secondString="456";
}))("???");
label1.Text=firstString+secondString;
Debug.Print("{0}", label1.Text);
or name the delegate and reuse it:
var firstString=default(String);
var secondString=default(String);
Action<String> m=
arg => {
firstString="abc"+arg;
secondString="xyz";
};
m("wtf");
label1.Text=firstString+secondString;
Debug.Print("{0}", label1.Text);
m("???");
label1.Text=firstString+secondString;
Debug.Print("{0}", label1.Text);
So, do you really need a method returns multiple values?
Each method can return only one value. Thats how methods defined in .NET
Methods are declared in a class or struct by specifying the access
level such as public or private, optional modifiers such as abstract
or sealed, the return value, the name of the method, and any method
parameters
If you need to return more than one value from method, then you have three options:
Return complex type which will hold all values. That cannot help you in this case, because you will need local variable to store value returned by method.
Use out parameters. Also not your case - you will need to declare parameters before method call.
Create another method, which does all work and returns single value.
Third option looks like
Label1.Text = AnotherMethod(parameters);
And implementation
public string AnotherMethod(parameters)
{
// use option 1 or 2 to get both values
// return combined string which uses both values and parameters
}
BTW One more option - do not return values at all - you can use method which sets several class fields.

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

Passing enumerated values to functions

Say I have a function that takes an integer as an argument. I'd like to be able to use an enumerated list as a way to keep the integer values organized.
For example, I'd ideally like to be able to define these (pseudocode):
public enum days
{
monday,
tuesday,
etc...
}
public enum months
{
january,
february,
etc...
}
int doSomething(enum x)
{
return x + 1;
}
and then be able to call the function using either of the enumerated lists like this:
int a = doSomething(days.monday);
int y = doSomething(months.february);
This obviously won't work as-is because doSomething needs to be defined using just one of the enumerations (i.e. either days or months). I know of a couple of options. One is to simply cast to an int:
int a = doSomething((int)days.monday);
int y = doSomething((int)months.february);
The only problem with this is that this function gets called MANY places in my code, and it's clumsy to have to keep putting "(int)"s all over the place (one of the main motivations for grouping these int values together into enums in the first place is to make the code more readable).
Another option is to avoid enums altogether, and instead bundle the values into a container class, something like:
static class Days
{
static int x = 0;
static int monday = x++;
static int tuesday = x++;
}
Again, this will work but just seems awfully cumbersome when I have a lot of these container classes to define.
The answer might very well be that there is no simpler way, and that I need to be a grown-up and just accept one of these options. But I thought I would get a sanity check on that before committing to it. Is there a third option?
What is your issue?
public enum Days : short
{
Monday = 1,
Tuesday = 2,
...
}
DoSomething(Days.Monday);
void DoSomething(Days day)
{
Days nextDay = day + 1;
}
Also note already built-in enum System.DayOfWeek.
I got OP's point but afaik this is not supported by C# yet:
void DoSomething<T>(T e) where T : enum
{
T next = e + 1;
}
Any problem with System.DateTime?
This would be the most pragmatic type to use.
You could overload your method, if you really just want the int value, perhaps something like this?
int dosomething(enum x)
{return dosomething((int)x)}
int dosomething(int x)
{return x+1}
yes you can do so
public enum days : int
{
monday,
tuesday,
...
}
automatically monday becomes 0 and tuesday becomes 1 and so on
public enum months : int
{
january,
february,
...
}
same for months
int doSomething(Enum x)
{
return (int)x + 1;
}
and call it as
int a = doSomething(days.monday);
or call it as
int a = doSomething(months.january);
now days.monday equals 0 and after method a becomes 1.
Or if you don't want to change all existing Enums:
public static int DoSomething(Enum x)
{
int xInt = (int)Convert.ChangeType(x, x.GetTypeCode());
DoSomething(xInt);
}
as stated here: enums-returning-int-value
public enum days : int
{ monday, tuesday,
}
public enum months :int
{ january, february, march,
}
public int doSomething(int z)
{
return z + 1;
}
// your calling method int c = ee.doSomething((int)testenums.months.march); int c = ee.doSomething((int)testenums.day.February);
working code as you always pass enum and which is of type int you just need to parse and send this code perfectly works.. let me know
DId you try to overload a function by parameter:
int DoSomething(Enum1 value)
int DoSomething(Enum2 value)
I spent a “little” time on this, because got a same problem(solution).
So here is my solution which work fine on (.NET 4), Windows Forms:
VB:NET
Private Function DoSomething(Of TEnum As {IComparable, IConvertible, IFormattable})(ByVal valueEnum As TEnum) As Int32
Dim i As Int32 = CInt(Convert.ChangeType(valueEnum, valueEnum.GetTypeCode()))
//Do something with int
i += 1
Return i
End Function
C#
private int DoSomething<TEnum>(TEnum valueEnum) where TEnum: IComparable, IConvertible, IFormattable
{
int i = 0;
i = (int)Convert.ChangeType(valueEnum, valueEnum.GetTypeCode());
i++;
return i;
}

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