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

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.

Related

C# anonymous function log method body

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.

Parallel.For<int> not working as expected

I wrote a simple Parallel.For loop. But when i run the code, i get random results. I expect var total to be 15 (1+2+3+4+5). I used Interlocked.Add to prevent from race conditions and strange behavior. Can someone explain why the output is random and not 15?
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("before Dowork");
DoWork();
Console.WriteLine("After Dowork");
Console.ReadLine();
}
public static void DoWork()
{
try
{
int total = 0;
var result = Parallel.For<int>(0, 6,
() => 0,
(i, status, y) =>
{
return i;
},
(x) =>
{
Interlocked.Add(ref total, x);
});
if (result.IsCompleted)
Console.WriteLine($"total is: {total}");
else Console.WriteLine("loop not ready yet");
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
}
}
Instead of using
(i, status, y) =>
{
return i;
}
you should use
(i, status, y) =>
{
return y + i;
}
Parallel.For splits the source sequence into several partitions. The items in each partition are processed sequentially, but multiple partitions may be executed in parallel.
Each partition has a local state. The local state is the return value of the the above lambda function and it is also passed as the y parameter. So the reason for returning y + i should be clear now: you should update the local state to the sum of the previous state and the input value i.
After every item of a partition has been processed, the final value of the local state is passed to the last function, where you sum up all the states:
(x) =>
{
Interlocked.Add(ref total, x);
}

Call any one of a number of functions until we get a specified result

I've got this ugly bit of code that looks a bit like this ...
TestResult GetFirstTestResult()
{
var result = TestMethod1();
if(result is EmptyResult)
{
result = TestMethod2();
}
if(result is EmptyResult)
{
result = TestMethod3();
}
// ...
if(result is EmptyResult)
{
result = TestMethodN();
}
return result;
}
Basically, I need to run a number of tests until I find one that has some values.
Now whilst the above code isn't pretty, for a small(ish) value of N is is managable. Sadly, in my case, N could get fairly big.
Is there a way of writing this using a loop, something along the lines of this pseudo code...
TestResult GetFirstTestResult()
{
TestResult[] results = {TestMethod1(), TestMethod2(), TestMethod3(), .. TestMethodN()};
return results.First(test=>!test.Result is Emptyresult);
}
such that each of the test methods were invoked in the loop so only the minimum number of them were actually executed?
EDIT
With thanks to Ric and Simon I've got this...
TestResult GetFirstTestResult()
{
return new Func<TestResult>[]
{
TestMethod1,
TestMethod2,
TestMethodN
}.Select(t => t())
.FirstOrDefault(r => !(r is EmptyResult)) ?? new EmptyResult();
}
which calls each method in turn until it finds one where the result is not of type EmptyResult and returns that. If no such result is found it returns new EmptyResult()
Something like this? Obviously I don't have all your code so cannot verify the correctness, but you should be able to modify as you require:
List<Func<TestResult>> methods = new List<Func<TestResult>>() { TestMethod1, TestMethod2, TestMethod3 };
foreach(var f in methods)
{
if(f().Result != EmptyResult)
{
break; //or something else
}
}
Simple solution using delegates:
class Program
{
static void Main(string[] args)
{
List<Func<int>> tests = new List<Func<int>>() { T1, T2, T3 };
Func<int> test = tests.First(t => t() != 0);
Console.WriteLine("Test is " + test.Method.Name);
}
static int T1() { return 0; }
static int T2() { return 1; }
static int T3() { return 1; }
}

Return string when inside a while loop

I've tried google, and the advance search here. No luck.
Class SomeClass
{
public string MethodName()
{
//Some Code
While(conditions)
{
//More Code
string X;
X = "string stuff";
return X;
}
}
}
I get a 'not all code paths return a value' error. I'm sure I can work around this but I'd like to know how to solve this for future reference.
Think if while loop condition is not met, would your method return string? So put the return just before end of method to ensure that your method will always return string, this MSDN error page not all code paths return a value would further help you to understand.
I believe the sample code is just to show the problem as it does not make much sense to me.
public string MethodName()
{
//Some Code
While(conditions) {
//More Code
string X;
X = "string stuff";
return X;
}
return "somestringifnotX";
}
You are getting error because you are trying to return value from while loop which is not possible
Problem here if your while loop condition is not satisfied than no value get return that is the reason compiler giving you error.
Solution to this is , return empty string outside while loop that you function is returning value.
public string functionname
{
while(conditions)
{
//More Code
string X;
X = "string stuff";
return X;
}
return string.Empty;
}
The problem is that the compiler believes there is a path where conditions is NOT met on the first time it hits the while:
//Some Code
while(conditions)
{
//More Code
string X;
X = "string stuff";
return X;
}
.. Problem!
return "not found"; // or throw new Exception("I'm not supposed to be here")
What you need to do is also return (or throw!) in the instance where conditions aren't met at all.
I think you mean this
static void Main(string[] args)
{
for (int i = 0; i < MethodName().Count; i++ )
{
var result = MethodName()[i] as string;
Console.WriteLine(result);
}
Console.ReadLine();
}
private static List<string> MethodName()
{
var items = new List<string>();
while (Condition)
{
items.Add("SString to return");
}
return items;
}
I hope it will help
Your problem is that you will not return anything when you don't pass your while loop
Class SomeClass
{
public string MethodName()
{
//Some Code
While(conditions)
{
//More Code
string X;
X = "string stuff";
return X;
}
return "Nothing to return Actually";
//OR
Throw new Exception("Conditions where false");
}
}
Imagine you're conditions = false and you never entered the while. This means you will never get to the return. your function on the other hand needs one. End your statement with a return or throw an error when you don't want that behaviour.
public static string binarySearch(int [] dataArray, int dataDicari)
{
int first = 0;
int last = list.length – 1;
int mid;
while (first <= last)
{
mid = (first+last)/2;
if (dataArray[mid] == dataDicari)
return ......; //ISIAN 1
else if (dataArray[mid] < dataDicari)
first = mid + 1;
else if (dataArray[mid] > dataDicari)
last = mid – 1;
}
return .....; //ISIAN 2
}

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

Categories

Resources