I have two similar functions I hope to refactor to remove duplication:
IEnumerable<TotalType> GetTotalForMonths(string id, DateTime lastTotalDate)
{
for (int i = 0; lastTotalDate.AddMonths(i + 1) <= DateTime.Now; i++)
{
var totalStartDate = new DateTime(lastTotalDate.AddMonths(i).Year, lastTotalDate.AddMonths(i).Month, 1);
var totalEndDate = totalStartDate.AddMonths(1);
var total = this.GetTotal(id, totalStartDate, totalEndDate);
yield return new TotalType(id, total, new TimeInterval(totalStartDate, totalEndDate));
}
}
The other does the same thing for days. I hope to pass in a delegate to generic-ize the particular duration (days, months, etc). I tried passing in Func<DateTime, DateTime> addTime, which works well, except that I don't want to specify addTime's arg value.
Suggestions?
var byMonths = GetTotal(123, yourDate, (d, i) => d.AddMonths(i));
var byDays = GetTotal(456, anotherDate, (d, i) => d.AddDays(i));
// ...
IEnumerable<TotalType> GetTotal(
string id, DateTime lastTotalDate, Func<DateTime, int, DateTime> adder)
{
for (int i = 0; adder(lastTotalDate, i + 1) <= DateTime.Now; i++)
{
var temp = adder(lastTotalDate, i);
var totalStartDate = new DateTime(temp.Year, temp.Month, 1);
var totalEndDate = adder(totalStartDate, 1);
var total = this.GetTotal(id, totalStartDate, totalEndDate);
var interval = new TimeInterval(totalStartDate, totalEndDate);
yield return new TotalType(id, total, interval);
}
}
I'm not sure if I understood your question correctly, but if you want to pass AddMonth method as an argument, without specifying the receiver object, you can construct a lambda:
GetTotal(id, lastDate, (dt, num) => dt.AddMonth(num))
to call the "genericized" function.
You need to declare the function as:
IEnumerable<TotalType> GetTotal(string id, DateTime lastTotalDate,
Func<DateTime, int, DateTime> adder)
What you're seeking to do is called "Currying". I have a pattern which I use in vb.net for that purpose; I'm not sure it's the best pattern, but it should be adaptable to C# without too much trouble. Note that while using lambda expressions will limit your ability to use edit-and-continue, use of a curry factory will pose no such restriction.
Here's a link to my question: What is the best pattern to curry delegate parameters (using .NET 2.0 or later)?
That should translate nicely into C#; any time you see parentheses starting with "(Of", replace them with angle brackets; "ByRef Foo As Bar" and "Dim Foo As Bar" both become "Bar Foo".
Related
I have code like this:
int i = 1;
string dynemicString = $"i = {i}";
while(i<10)
{
Console.WriteLine(i);
i++;
}
And I want to get result like this:
i = 1
i = 2
i = 3
...
How to do it?
int i = 1;
while(i<10)
{
Console.WriteLine($"i = {i}");
i++;
}
For more information read about String Interpolation
If you want a more tokenized way of doing this, use String.Format
int i = 1;
string dynemicString = "i = {0}";
while(i<10)
{
Console.WriteLine(string.Format(dynemicString,i));
i++;
}
Here's an alternative approach to TheGeneral's answer. I'm not suggesting using it, but I find it an "interesting" idea just for the sake of learning a bit more about how string interpolation works.
When an interpolated string literal is converted to a string, all the expressions are immediately evaluated and the string is formatted. The string can't change afterwards.
When an interpolated string literal is converted to a FormattableString, the expressions are evaluated, but the string formatting isn't performed. Instead, the results of all the expressions are stored for later formatting. Every time you call ToString on a FormattableString, the formatting is performed again.
So, we can make it dynamic by making the same values (as evaluated initially) return different strings when string formatting happens. One simple - but really ugly - way of doing that is to use a delegate to capture i, and then put the delegate in a wrapper that overrides ToString and executes the delegate each time. Here's a complete example of that:
// CODE FOR EDUCATIONAL PURPOSES ONLY. DON'T USE IN PRODUCTION!
using System;
public class FuncWrapper
{
private readonly Func<string> func;
public FuncWrapper(Func<string> func) =>
this.func = func;
public override string ToString() => func();
}
class Test
{
static void Main()
{
int i = 1;
// Capture i in a delegate; each time the delegate
// is executed, you'll get a different value. Each
// time ToString is called, the delegate will be called
var wrapper = new FuncWrapper(() => i.ToString());
FormattableString dynamicString = $"i = {wrapper}";
while (i < 10)
{
Console.WriteLine(dynamicString);
i++;
}
}
}
Output:
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9
I was wondering, if I use Lambda expressions correctly in the following short code snippet? I want to store function calls over time and then execute them all together in Update_Calls(). Most importantly, I am asking whether the parameters var1-3 keep their value (the value they had when calling Extern_Func()) in ANY case?
static List<Action> callsForUpdate = new List<Action>();
public static void Extern_Func(int var1, int var2, float var3)
{
Action callToStore = () => Func(var1, var2, var3);
// Remember in call list
callsForUpdate.Add(callToStore);
}
public static void Update_Calls()
{
for (int i = 0; i < callsForUpdate.Count; i++)
{
callsForUpdate.ElementAt(i);
}
callsForUpdate.Clear();
}
Yes. They will be retained. Your Update_Calls has an issue.
public static void Update_Calls()
{
for (int i = 0; i < callsForUpdate.Count; i++)
{
callsForUpdate.ElementAt(i)();
}
callsForUpdate.Clear();
}
You were only referring the element. Not calling it.
What you are creating is called Closure, which means that Action will be called with the current values of var1, var2, var3, in this case they are local variables of Extern_Func, so unless you change them in that method (Extern_Func) they will keep their value.
What you are doing is creating an expression pointed to by each item in the callsForUpdate list. Expressions are immutable. In order to change the values you supplied in an expression, the expression must be replaced by a new expression with new values.
In my best estimation of what you are asking is true for most any case because your list is simply a list of expressions to be executed with the values supplied at the time they were created by Etern_Func.
Closures capture variables, not values. Make sure that is clear.
In your case, var1, var2 and var3 are passed by value arguments that can only be changed locally. Therefore if you don't change them inside Extern_Func you are good to go.
To understand the difference between capturing values or variables, consider the following snippet:
var funcs = new List<Action>();
for (var i = 0; i < 5; i++)
{
var temp = i;
funcs.Add(() => Console.WriteLine(i));
funcs.Add(() => Console.WriteLine(temp));
}
foreach (var f in funcs)
{
f();
}
Can you guess the output?
We have semi-complicated expressions in the format:
"25 + [Variable1] > [Variable2]"
We need an expression evaluator to parse the expression and use a callback to ask for the variable values and work out the overall result of the expression. It has to be a callback as there are thousands of variables.
We need the usual math operators but also things like "if" etc. The richer the language the better.
We can use any language we want. Anyone have any suggestions?
Have you considered using Mono.CSharp.Evaluator? It seems like this in conjunction with an appropriatelly set InteractiveBaseClass would do the trick quite nicely, and with minimal effort.
Note that the following uses Mono 2.11.1 alpha.
using System;
using System.Diagnostics;
using Mono.CSharp;
using NUnit.Framework;
public class MonoExpressionEvaluator
{
[Test]
public void ProofOfConcept()
{
Evaluator evaluator = new Evaluator(new CompilerContext(new CompilerSettings(), new ConsoleReportPrinter()));
evaluator.InteractiveBaseClass = typeof (Variables);
Variables.Variable1Callback = () => 5.1;
Variables.Variable2Callback = () => 30;
var result = evaluator.Evaluate("25 + Variable1 > Variable2");
Assert.AreEqual(25 + Variables.Variable1 > Variables.Variable2, result);
Console.WriteLine(result);
}
public class Variables
{
internal static Func<double> Variable1Callback;
public static Double Variable1 { get { return Variable1Callback(); } }
internal static Func<double> Variable2Callback;
public static Double Variable2 { get { return Variable2Callback(); } }
}
}
Real shame it runs a little slow. For instance, on my i7-m620 it takes almost 8 seconds to run this 10,000 times:
[Test]
public void BenchmarkEvaluate()
{
Evaluator evaluator = new Evaluator(new CompilerContext(new CompilerSettings(), new ConsoleReportPrinter()));
evaluator.InteractiveBaseClass = typeof(Variables);
Variables.Variable1Callback = () => 5.1;
Variables.Variable2Callback = () => 30;
var sw = Stopwatch.StartNew();
for (int i = 1; i < 10000; i++)
evaluator.Evaluate("25 + Variable1 > Variable2");
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
00:00:07.6035024
It'd be great if we could parse and compile it to IL so we could execute it at .NET speeds, but that sounds like a bit of a pipe dream...
[Test]
public void BenchmarkCompiledMethod()
{
Evaluator evaluator = new Evaluator(new CompilerContext(new CompilerSettings(), new ConsoleReportPrinter()));
evaluator.InteractiveBaseClass = typeof(Variables);
Variables.Variable1Callback = () => 5.1;
Variables.Variable2Callback = () => 30;
var method = evaluator.Compile("25 + Variable1 > Variable2");
object result = null;
method(ref result);
Assert.AreEqual(25 + Variables.Variable1 > Variables.Variable2, result);
Variables.Variable2Callback = () => 31;
method(ref result);
Assert.AreEqual(25 + Variables.Variable1 > Variables.Variable2, result);
var sw = Stopwatch.StartNew();
for (int i = 1; i < 10000; i++)
method(ref result);
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
00:00:00.0003799
Oh my.
Need excel-like expression constructs like IF? Build your own!
[Test]
public void ProofOfConcept2()
{
Evaluator evaluator = new Evaluator(new CompilerContext(new CompilerSettings(), new ConsoleReportPrinter()));
evaluator.InteractiveBaseClass = typeof(Variables2);
Variables.Variable1Callback = () => 5.1;
Variables.Variable2Callback = () => 30;
var result = evaluator.Evaluate(#"IF(25 + Variable1 > Variable2, ""TRUE"", ""FALSE"")");
Assert.AreEqual("TRUE", result);
Console.WriteLine(result);
}
public class Variables2 : Variables
{
public static T IF<T>(bool expr, T trueValue, T falseValue)
{
return expr ? trueValue : falseValue;
}
}
Check out NCalc. It's .NET and should support your requirements.
Pure expression evaluators are actually pretty easy to write.
See this SO answer which shows expression evaluators in a dozen langauges. You should be able to adapt one of these:
Code Golf: Mathematical expression evaluator (that respects PEMDAS)
EDIT: Whoever dinged this obviously didn't go and examine the solutions there. Yes, there are a bunch that are crammed tight to meet the golf-rules (typically "smallest") but most of them are explained pretty clearly with a cleartext version of algorithm.
Well ... you need a language. You have C#, VB.Net, IronPython, IronRuby, and others.
Simple replace the open variables using regex (maybe you even know them ahead and just need a string.Replace) and then compile the script using CodeDOM (for C# or VB.Net) or use the DLR (IronPython, IronRuby). You can simply add the variables as method parameters in the method wrapper you use to encapsulate your code (for CodeDOM) or just inject the variables in the DLR.
Both variants we implemented in our team in business with less effort and reliable effort.
When you urgently regquire the callback, well the add to the solutions above a method which communicate with the host of the programming language with a name like ValueOf(string). So you can write
ValueOf("A") > ValueOf("B") - 10
Have fun.
http://code.google.com/p/bc-expression/
Handles variable lookup via a lambda or block callback.
Understands numeric, string and boolean constants.
Unary operators + - !
Operators || && < <= == != >= > + - * / %
Grouping with ( )
Raises an Expression::SyntaxError if there's a syntax error.
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.
I want to write a method which can take an arbitrary array of a numeric type and return the sum of all the elements between startIndex and endIndex. This is what I have:
private static T SumArrayRange<T>(T[] scores, int startIndex, int endIndex)
{
T score = 0;
for (int i = startIndex; i <= endIndex; i++)
{
score += scores[i];
}
return score;
}
But the compilation fails with these 2 errors.
Cannot implicitly convert type 'int'
to 'T'.
Operator '+=' cannot be
applied to operands of type 'T' and
'T'
Is there any way I can force T to be only one of the numeric types (long, double etc.)? Or is their a more elegant way of solving this?
No, there's no way to constrain generic type parameters to use operators, and there are no good workarounds for that, either. A proper one would be an interface such as INumeric or IArithmetic with methods such as Add, Subtract etc, implemented by all primitive types such as int and long. There is a 5-year old feature request for that in MS Connect, which is still Active. The latest word on that is:
Unfortunately, we've had to cut our plans to solve this problem in the .NET Framework 4.0.
Until then, you are relegated to either:
using Reflection yourself - messy and very slow
using any of the existing wrappers that will use Reflection for you (e.g. Microsoft.VisualBasic.CompilerServices.Operators class, with methods such as AddObject, SubtractObject etc which use reflection and implement VB semantics for the corresponding operators) - easy to use, but still very slow
hardcoding types you want to handle (i.e. no support for overloaded arithmetic operators on user-defined types), and using a giant if (x is int) ... else if (x is double) ... statement.
Another approach is to use the LINQ tools that are already available, rather than writing your own. For example:
var mySum = myCollection.Skip(startIndex).Take(count).Sum();
Since the Sum extension method exists for all of the built-in numeric types, you don't have to worry about writing your own. Of course, this won't work if your code's "myCollection" variable is already of a generic collection type.
This approach works pretty well:
http://www.codeproject.com/KB/cs/genericnumerics.aspx
The solution is in dynamic keyword.
T score = default(T)
for (int i = startIndex; i <= endIndex; i++)
{
score += (dynamic)scores[i];
}
return score;
It is a concept named late binding.
There is no type to which you can constrain T that will allow the += operator to work. This is because .NET does not have a type that means numeric.
This is because T could be any type. If T was a HttpWebRequest could you assign 0 to it, or could you use the += operator on it?
You can get around the first error by using
T score = default(T);
I'm not sure how you'd deal with the second because you'd have to constrain T to be types that implement a += operator.
Generic constraints are the only possiblilty I can think of. But, being drunk, I can't exactly test this!
I'm perhaps being stupid, but won't int.Parse() fix this problem?
Here my variant
uses binary operator "add" of type T as default,
but offers ability to customize the add function for some specified types, and use the default binary add only for the rest
(throwing an exception at runtime if binary add isn't defined for type T).
private static Func<T, T, T> CreateAdd<T>()
{
Func<T, T, T> addMethod = null;
Expression<Func<T, T, T>> addExpr = null;
if (typeof(T) == typeof(string))
{
//addExpr = (Expression<Func<T, T, T>>)((a, b) => ((T)(object)((string)(object)a + (string)(object)b)));
//addMethod = addExpr.Compile();
addMethod = (a, b) => {
string aa = (string)(object)a;
string bb = (string)(object)b;
double da;
double db;
double.TryParse(aa, out da);
double.TryParse(bb, out db);
double c = da + db;
string res = c.ToString();
return (T)(object)res;
}; // End Delegate addMethod
}
else
{
ParameterExpression lhs = Expression.Parameter(typeof(T), "lhs");
ParameterExpression rhs = Expression.Parameter(typeof(T), "rhs");
addExpr = Expression<Func<T, T, T>>.Lambda<Func<T, T, T>>(
Expression.Add(lhs, rhs),
new ParameterExpression[] { lhs, rhs }
);
addMethod = addExpr.Compile();
}
return addMethod;
}
// MvcTools.Aggregate.Functions.Sum<T>(vals);
public static T Sum<T>(params T[] vals)
{
T total = default(T);
//Enumerable.Aggregate(vals, delegate(T left, T right) { return left + right; });
Func<T, T, T> addMethod = CreateAdd<T>();
foreach (T val in vals)
{
total = addMethod(total, val);
}
return total;
} // End Function Sum
Example:
int[] vals = new int[] { 1, 2, 3, 4, 5 };
int sum = MvcTools.Aggregate.Functions.Sum<int>(vals);
double[] dvals = new double[] { 1, 2, 3, 4, 5 };
double dsum = MvcTools.Aggregate.Functions.Sum<double>(dvals);
string[] strs = new string[] { "1", "2", "3", "4", "5" };
string str = MvcTools.Aggregate.Functions.Sum<string>(strs);
output: 15, 15.0, "15"