C# anonymous function log method body - c#

I am working on an application where we need to log entire statement of anonymous (lambda) function.
What it means is that the "LogAction" method should log all the statements that are passed as action.
protected void LogAction(Action action)
{
/*
Log the statement(s) passed to this method i.e. should print
var a = 10;
var b = 20;
Console.WriteLine($"Sum of {a} and {b} is {a+b}");
*/
}
LogAction(() =>
{
var a = 10;
var b = 20;
Console.WriteLine($"Sum of {a} and {b} is {a+b}");
});

You can use the Expression class in C#:
Expression<Action> ex = () => System.Console.WriteLine("Hello world");
Console.WriteLine(ex.ToString());
The above code will print () => WriteLine("Hello world") on the console. This should help enough for debugging purposes. Unfortunately it does not provide as much flexibility as one would expect. For example the following initialization will give you an error:
//ERROR: A lambda expression with a statement body cannot be converted to an expression tree
Expression<Action> ex = () =>
{
int a = 10;
int b = 21;
Console.WriteLine(a + b);
};
A way around this is to define a method which you can later on assign to the Expression object:
void Sum()
{
int a = 10;
int b = 21;
Console.WriteLine(a + b);
}
Valid assignment:
Expression<Action> ex = () => Sum();
Console.WriteLine(ex.ToString());
The above code prints () => Sum() on the console.

Related

how to have a function containing a sub function in C#

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

How to get result from `new Func<T>() { ... }?`

Why do these print different things?
Let's say I have such class:
public class ExampleOfFunc
{
public int Addition(Func<int> additionImplementor)
{
if (additionImplementor != null)
return additionImplementor();
return default(int);
}
}
And in the Main method:
This prints 200:
ExampleOfFunc exampleOfFunc = new ExampleOfFunc();
Console.WriteLine("{0}", exampleOfFunc.Addition(
() =>
{
return 100 + 100;
})); // Prints 200
But this prints Prints System.Func'1[System.Int32]:
Console.WriteLine("{0}", new Func<int>(
() =>
{
return 100 + 100;
})); // Prints System.Func`1[System.Int32]
This line
return additionImplementor();
Calls the function and returns its result which is then passed to Console.WriteLine().
While this line
Console.WriteLine("{0}", new Func<int>(
() =>
{
return 100 + 100;
}
));
merely passes the function to Console.WriteLine() without calling it. Add () to execute the function before printing it out...
Console.WriteLine("{0}", new Func<int>(
() =>
{
return 100 + 100;
}
)());
Fiddle
In the second example you only supply the anonymous function as a parameter to Console.WriteLine. You don't actually call the function.
Imagine there are fifty classes and functions such as ExampleOfFunc.Addition. How would compiler know which function you had in mind? You have to tell it explicitly.

Declaring Thread syntax understanding

While reading a book named "Programming in C#", I've came across a syntax that I fail to understand :
public static void Main(string[] args)
{
new Thread( () =>
{
for(int x = 0; x < 10; x++)
{
_field++;
Console.WriteLine("Thread A : {0}", _field);
}
}).Start();
}
What does " () => " refers to, and what constructor is called ? I tried to google it but "() =>" is kinda hard to search on google.
This is a lambda expression, see here for the docs.
More specifically, it is an anonymous function. The Thread constructor requires a function that is called when the thread starts. Rather than creating a function for re-use (void ThreadFunc() { ... }), an anonymous function is declared in-line.
I do not know C# but this looks like an anonymous function. That is the Thread Object will run this function once start is called, on a seperate thread.
EDIT: its called anonymous because it has no name, also () => {} are 'arguments' => 'fun-body'
() => ... just means that it is the lambda expression that takes no parameters. It is same as the following
without parameter:
void MyWork() // This is your class constructor
{
for(int x = 0; x < 10; x++)
{
_field++;
Console.WriteLine("Thread A : {0}", _field);
}
}
new Thread(MyWork).Start();
With Parameter:
void MyWork(int _number) // This is your class constructor
{
for(int x = 0; x < _number; x++)
{
_field++;
Console.WriteLine("Thread A : {0}", _field);
}
}
new Thread(() => MyWork(10)).Start();

references kept by anonymous methods and lambdas

are there any differences in the references that are produced in code generated for anonymous methods by a .NET 2.0 or 4.0 compiler and code generated for an equivalent lambda by a .NET 4.0 compiler? and in particular for the this pointer: I know both anonymous methods and lambdas are a C# compiler feature and the compiler actually generates a nested class with a delegate and all the references required for outer variables, but this article on the implementation of anonymous methods states a reference is kept to the pointer and I cannot find any source describing anything similar for lambdas.. or am I not finding anything because the implementation for compiling anonymous methods maps 1 on 1 to that of lambdas?
here's a bit of code to demonstrate anonymous methods and lambdas:
class AnonymousMethodMethodScope
{
private Func<bool> d;
public Func<int, bool> d2;
int j = 0;
public void Test(int i)
{
d = new Func<bool>(delegate { j = 10; return j > i; });
// what references does this anonymous method keep?
d2 = new Func<int, bool>(delegate(int x) { return x == j; });
Console.WriteLine("j = " + j + " result = " + d());
}
}
class LambdaMethodScope
{
private Func<bool> d;
public Func<int, bool> d2;
public void Test(int i)
{
int j = 0;
d = () => { j = 10; return j > i; };
// what references does this lambda keep?
d2 = x => x == j;
Console.WriteLine("j = " + j + " result = " + d());
}
}
Yes, lambda expressions will do (and have to do) the same thing as anonymous methods when it comes to capturing variables. (I'm assuming you're talking about lambda expressions which are converted into delegates; if they're converted into expression trees they may be a bit different - I'm not sure.)

How to use/understand lambda expressions?

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)));
}

Categories

Resources