Lets say I have the following code:
delegate int MyDel (int n); // my delegate
static int myMethod( MyDel lambda, int n) {
n *= n;
n = lambda(n);
return n; // returns modified n
}
This way, having different lambda expression I can tune the output of the Method.
myMethod ( x => x + 1, 5);
myMethod ( x => x - 1, 5);
Now, if I don't want to do any aritmethic in lambda expression, I could use:
myMethod ( x => x, 5); // and lambda will simply return x
My question is, is there a way to use the lambda expresion with 'params' optional properties? Maybe somehow embedding my delegate in array?
static int myMethod (int n, params MyDel lambda) {
Does this work?
EDIT
Sorry, was doing this with one eye, let me rephrase that.
static int myMethod (int n, params MyDel[] lambdas) {
Yes you can.
delegate int MyDelegate(int n);
static void MyMethod(int n, params MyDelegate[] handlers)
{
for (int i = 0; i < handlers.Length; i++)
{
if (handlers[i] == null)
throw new ArgumentNullException("handlers");
Console.WriteLine(handlers[i](n));
}
}
static void Main(string[] args)
{
MyMethod(1, x => x, x => x + 1);
Console.Read();
}
Output:
1
2
Related
I need to create a function, that will take another functions (always different quantity of them). Can someone help me please?
Function DoThisFunction will have different types and quantity of parameters.
there can be different number of condition functions.
I'll try to show it here:
bool MyFunction(condition1(args), condition2(args), condition3(args), ... , DoThisFunction(args))
{
...
if (condition1(int x) == true && condition2(int x, string C) == 5)
{
DoThisFunction(par1, par2, par3 ...);
return true;
}
}
bool condition1(int x)
{
if (x>5)
return true;
else
return false;
}
int condition2(int x, string C)
{
....
return par1;
}
etc...
Then I need to call:
bool z = MyFunction(condition1(int x)==true, condition2(int x, string C)==5, DoThisFunction(par1, anotherArguments ...))
I would like to suggest another approach for your code.
Maybe, you can keep a separated list with all the functions you need to verify, and run each method inside a very simple loop (foreach), in this case:
the code will be very friendly (easy to understand)
better maintainability
you can review less code and add more functionality (for instance, you may inject some code and just add another Func<> into your List<>)
Please, take a look at the following example:
static class Program
{
private static void Main(string[] args)
{
var assertions = new List<Func<object[], bool>>
{
Assertion1,
Assertion2,
Assertion3
};
var yourResult = Assert(assertions, 1, "1", true);
Console.WriteLine(yourResult); // returns "True" in this case
Console.ReadLine();
}
private static bool Assert(IEnumerable<Func<object[], bool>> assertions, params object[] args)
{
// the same as
// return assertions.Aggregate(true, (current, assertion) => current & assertion(args));
var result = true;
foreach (var assertion in assertions)
result = result & assertion(args);
return result;
}
private static bool Assertion1(params object[] args)
{
return Convert.ToInt32(args[0]) == 1;
}
private static bool Assertion2(params object[] args)
{
return Convert.ToInt32(args[0]) == Convert.ToInt32(args[1]);
}
private static bool Assertion3(params object[] args)
{
return Convert.ToBoolean(args[2]);
}
}
This solution seems to generic for your problem.
For checking preconditions before executing methods have a look at Code Contracts
You can use functor like the following:
private bool MyFunction(Func<int, bool> condition1, Func<int,string,int> condition2, Func<int,string,int, int> doThisFunction, int x, string str)
{
if (condition1(x) && condition2(x, str) == 5)
return doThisFunction(x, str, x) == 10;
return false;
}
Then call this function in your code like the below:
MyFunction(x => x > 5 ? true : false, (x, C) => C.Length == x * 5 ? 5 : C.Length,
(x, str, y) =>
{
if (x + y > str.Length)
return 5;
else if (x * y > 5)
return 10;
else
return 15;
}, 10, "Csharp");
I have a part of code which is repeated multiple time in a function. However I'd like to make a function of it, but I'd like it to know the variables of my function so it can modify them without the need to pass them (because there is a lot).
example of what I want to accomplish
static void Main(string[] args)
{
int x = 0
subfunction bob()
{
x += 2;
}
bob();
x += 1;
bob();
// x would equal 5 here
}
Use Action:
static void Main(string[] args)
{
int x = 0;
Action act = ()=> {
x +=2;
};
act();
x += 1;
act();
// x would equal 5 here
Console.WriteLine(x);
}
You could wrap your parameters into a class.
public class MyParams
{
public int X { get; set; }
}
public static void bob(MyParams p)
{
p.X += 2;
}
static void Main()
{
MyParams p = new MyParams { X = 0 };
bob(p);
p.X += 1;
bob(p);
Console.WriteLine(p.X);
}
This is roughly what the lambda answers are doing behind the scenes.
You can do this by using a lambda expression:
public static void SomeMethod () {
int x = 0;
Action bob = () => {x += 2;};
bob();
x += 1;
bob();
Console.WriteLine(x); //print (will be 5)
}
The lambda expression is the following part() => {x += 2;}. The () denotes that the action takes no input at all. Between accolades, you can then specify the statements that should be executed. Variables not defined on the left of the lambda expression (llike x) are bounded like the normal rules of scoping in the C/C++/Java language family. Here x thus binds with the local variable x in SomeMethod.
Action is a delegate, it refers to a "method", and you can call it as a higher-order method.
Note that your code is not C#. You cannot write int main as main method.
Demo (Mono's C# interactive shell csharp)
$ csharp
Mono C# Shell, type "help;" for help
Enter statements below.
csharp> public static class Foo {
>
> public static void SomeMethod () {
> int x = 0;
> Action bob = () => {x += 2;};
> bob();
> x += 1;
> bob();
> Console.WriteLine(x);
> }
>
> }
csharp> Foo.SomeMethod();
5
If I have function like this
double GetExpression(int x, int y, int z)
{
return x * y + z;
}
is it possible to modify it somehow, to not return result immediately only some object which is expression and then evaluate it this way:
var expression = GetExpression(1,2,3);
double result = expression.Execute() or expression.Evaluate()
other words just return function
?
Yes!
Func<double> GetExpression(int x, int y, int z)
{
return () => x * y + z;
}
use as:
var expression = GetExpression(1,2,3);
double result = expression();
Well, you could use delegates, and return a Func<double>:
Func<double> GetExpression(int x, int y, int z)
{
return () => x * y + z;
}
var expression = GetExpression(1,2,3);
double result = expression(); // Or expression.Invoke()
Is that what you were looking for?
Now each time you call expression() it will execute the code in the lambda expression. You can observe that if you use code which doesn't just return the same value each time. For example:
Func<int> GetExpression()
{
Random rng = new Random();
return () => rng.Next(10);
}
var expression = GetExpression();
for (int i = 0; i < 10; i++)
{
Console.WriteLine(expression());
}
That will print 10 random numbers in the range [0, 10). Note that this will only create one instance of Random (avoiding a common problem) - each time you call expression() it will call the Next() method on the same instance. The constructor for Random is called in the "normal" part of the method - it's not in the lambda expression. So that gets executed when you first call the GetExpression method (even if you never call expression() afterwards).
Note however that the arguments to your GetExpression were still passed by value though, and are captured by the lambda express. So consider this:
Func<int> GetExpression(int a, List<int> b)
{
return () => a + b.Count;
}
int x = 10;
List<int> list = new List<int> { 1, 2, 3 };
var expression = GetExpression(x, list);
Console.WriteLine(expression()); // 13
x = 20;
list.Add(100);
Console.WriteLine(expression()); // 14
Here the value of the list variable has been captured, so changes the the object that the value refers to are visible in the lambda expression, but changes to the x variable itself are not visible in the lambda expression. (Likewise if you had list = new List<int>(); that change wouldn't be visible...
To expand on Jon Skeet's answer, about capturing variables, if you didn't want to, you could do something like this:
double GetExpression(int x, int y, int z)
{
return x * y + z;
}
Func<int, int, int, double> expression = GetExpression;
for (int i = 0; i < 10; i++)
Console.WriteLine("{0}", expression(i, i+1, i+2));
Which avoids modifying the existing code (in case you wanted to point to a function you didn't have control over), and avoids capturing values outside of the lamda.
I have the following method:
private byte[] GetEmailAsBytes(string lstrBody)
{
byte[] lbytBody;
ASCIIEncoding lASCIIEncoding = new ASCIIEncoding();
lbytBody = lASCIIEncoding.GetBytes(lstrBody);
return lbytBody;
}
I was wondering if this could be converted to a lambda expression. Im new to this. I have tried:
Func<string> BodyToBytes = x => {
ASCIIEncoding lASCIIEncoding = new ASCIIEncoding();
return lASCIIEncoding.GetBytes(x);
}
but this does not compile. Simply i wish to convert a string to a series of bytes, and for interest sake would like to do this using lambda expressions.
The expression Func<string> is equivalent to a function which accepts no arguments and returns a string.
Your example clearly returns a byte[], but you want it to accept a string and return a byte[].
To solve this, change BodyToBytes to match the following. Note that the type of the arguments come first, comma delimited, followed by the return type. In this case, x will be of type string.
Func<string, byte[]> BodyToBytes = x => {
ASCIIEncoding lASCIIEncoding = new ASCIIEncoding();
return lASCIIEncoding.GetBytes(x);
}
For a reference, see Func Type or the MSDN docs.
I have writeen a NUnit Example for my personal understanding.
private class ld
{
public Boolean make<T>(T param, Func<T, bool> func)
{
return func(param);
}
}
private class box
{
public Boolean GetTrue() { return true; }
public int Secret = 5;
}
[Test]
public void shouldDemonstrateLambdaExpressions()
{
//Normal Boolean Statement with integer
int a = 5;
Assert.IsTrue(a == 5);
Assert.IsFalse(a == 4);
//Boolean Statement Expressed Via Simple Lambda Expression
Func<int, bool> myFunc = x => x == 5;
Assert.IsTrue(myFunc(5));
Assert.IsFalse(myFunc(4));
//Encapsuled Lambda Expression Called on Integer By Generic Class with integer
ld t = new ld();
Assert.IsTrue(t.make<int>(5,myFunc));
Assert.IsFalse(t.make<int>(4, myFunc));
//Encapsuled Lambda Expression Called on Integer By Generic Class with implicit Generics
Assert.IsTrue(t.make(5, myFunc));
//Simple Lambda Expression Called on Integer By Generic Class with implicit Generic
Assert.IsTrue(t.make(20, (x => x == 20)));
Assert.IsTrue(t.make(20, (x => x > 12)));
Assert.IsTrue(t.make(20, (x => x < 100)));
Assert.IsTrue(t.make(20, (x => true)));
//Simple Lambda Expression Called on a Class By Generic Class with implicit Generic
//FULL LAMBDA POWER REACHED
box b = new box();
Assert.IsTrue(t.make(b, (x => x.GetTrue())));
Assert.IsTrue(t.make(b, (x => x.Secret == 5)));
Assert.IsFalse(t.make(b, (x => x.Secret == 4)));
}
I'm just wondering if there is a C# equivilent for this python code.
I want to store the names of methods in some sort of collection and call them later on. I have searched, but I really don't know what to look for.
For example in python I could do:
def add_one(x):
return x + 1
def double_it(x):
return x*2
maths_rules = [add_one, double_it]
def do_maths(maths_rules, x):
for func in maths_rules:
x = func(x)
return x
print do_maths(maths_rules, 9)
# >>> 20
This is a silly example, but you should get the idea.
You are looking for delegates.
A delegate is a type that defines a method signature. When you instantiate a delegate, you can associate its instance with any method with a compatible signature. You can invoke
(or call) the method through the delegate instance.
Your example in C#, using the Func<T, TResult> Delegate:
int add_one(int x) { return x + 1; }
int double_it(int x) { return x * 2; }
var maths_rules = new List<Func<int,int>> { add_one, double_it };
int do_maths(IEnumerable<Func<int,int>> maths_rules, int x)
{
foreach (var func in maths_rules)
{
x = func(x);
}
return x;
}
Console.WriteLine(do_maths(maths_rules, 9));
// prints "20"
Yes, you can use delegates. For this one use Func<int, int>.
like:
int addone(int x)
{
return x + 1;
}
and in main:
Func<int, int> myFunc = new Func<int, int>(addone);
myFunc(5); // to use it, you can pass it as you like
example on your code:
static int add_one(int x)
{
return x + 1;
}
static int double_it(int x)
{
return x * 2;
}
static int do_maths(List<Func<int, int>> math_rules, int x)
{
foreach(var func in math_rules)
x = func(x);
return x;
}
static void Main(string[] Args)
{
List<Func<int, int>> math_rules = new List<Func<int, int>>();
math_rules.Add(new Func<int, int>(add_one));
math_rules.Add(new Func<int, int>(double_it));
Console.WriteLine(do_maths(math_rules, 9)); // 20
}
or use lambdas as suggested in comment:
static int do_maths(List<Func<int, int>> math_rules, int x)
{
foreach(var func in math_rules)
x = func(x);
return x;
}
static void Main(string[] Args)
{
List<Func<int, int>> math_rules = new List<Func<int, int>>();
math_rules.Add(new Func<int, int>((x) => (x + 1)));
math_rules.Add(new Func<int, int>((x) => (x * 2)));
Console.WriteLine(do_maths(math_rules, 9)); // 20
}