returning functions vs void functions setting variables - c#

New programmer here, I just wondered about this for a while. Take a look at this for instance, what is the difference between these ?:
static void Main(string[] args)
{
Program obj = new Program();
Console.WriteLine(Convert.ToString(obj.Add()));
}
int Add()
{
return 1 + 1;
}
and
int Sum;
static void Main(string[] args)
{
Console.WriteLine(Convert.ToString(Sum));
}
void Add()
{
Sum = 1+1;
}

The first case executes the method Add and prints the return value 2 to the console.
The second case will not compile because Sum is a class variable and you are missing a object reference like in the first case to access it.
If you would make Sum static then your Main will work and print simply the default value of Sum which is 0. Since you never call the Add method.
As for the difference of the two Add() methods:
The second case uses a class variable and manipulates it. It has to be called so that the value of Sum changes.
The first case uses only a local computation and does not change anything within the class. It simply returns the result of a calculation
EDIT:
What would be the difference between the two, which will be preferable?
It depends strongly on what you intend to do. If the only thing you are interested is the result of 1+1 and you need to use this result in some method like the Main then use the first case.
If the variable represents a significant feature of the class like this:
public class BillsToPay
{
public int Sum;
List<int> Bills = new List<int>() {3,5,6,7};
public void CalculateAllBills()
{
foreach (var bill in Bills)
{
Sum = Sum + bill;
}
}
}
Then you would have a method which manipulates the class variable Sum and updates its state. so the second version kicks in. But it is always a mixture of taste and intention of how to approach a given problem.
Small test program:
static void Main(string[] args)
{
BillsToPay btp = new BillsToPay();
btp.CalculateAllBills();
Console.WriteLine(Convert.ToString(btp.Sum));
}

Related

methods change variable out of its scope

In this small piece of code, changing a 2 dimensional array inside a method leads to changes the variable in main method.
What is the cause of this and how can I protect the variable in main method to remain unchanged?
using System;
namespace example
{
class Program
{
static void Main(string[] args)
{
string[,] string_variable = new string[1, 1];
string_variable[0, 0] = "unchanged";
Console.Write("Before calling the method string variable is {0}.\n", string_variable[0,0]);
Function(string_variable);
Console.Write("Why after calling the method string variable is {0}? I want it remain unchanged.\n", string_variable[0, 0]);
Console.ReadKey();
}
private static void Function(string [,] method_var)
{
method_var[0, 0] ="changed";
Console.Write("Inside the method string variable is {0}.\n", method_var[0, 0]);
}
}
}
At the end this is the program output:
Before calling the method string variable is unchanged.
Inside the method string variable is changed.
Why after calling the method string variable is changed? I want it remain unchanged.
EDIT 1: A question come in my mind is : What are other common programming languages that doesn't have this sort of problem?
EDIT 2: For sack of comparison, I write this somehow identical code with string variable instead of array and the output is as expected and is just fine:
using System;
namespace example
{
class Program
{
static void Main(string[] args)
{
string string_variable;
string_variable= "unchanged";
Console.Write("Before calling the method string variable is {0}.\n", string_variable);
Function(string_variable);
Console.Write("after calling the method string variable is {0} as expected.\n", string_variable);
Console.ReadKey();
}
private static void Function(string method_var)
{
method_var ="changed";
Console.Write("Inside the method string variable is {0}.\n", method_var);
}
}
}
and the output of this code is :
Before calling the method string variable is unchanged.
Inside the method string variable is changed.
after calling the method string variable is unchanged as expected.
Last EDIT : Thanks everybody for clarification, Hope this will become useful for others in future.
When you pass an array to a method (or any reference type), you're passing a reference to the memory where that array exists. So making a change to the array will behave exactly the same as if you'd made that change in the method in which the array was originally instantiated.
Unfortunately, there's no way to make an array read-only in C#. However, you could create a wrapper class as described here that provides a mechanism for accessing the values in the array, without providing a way to change the array. Then you could pass that wrapper class into Function instead of passing the array itself.
public class ReadOnlyTwoDimensionalArray<T>
{
private T[,] _arr;
public ReadOnlyTwoDimensionalArray(T[,] arr)
{
_arr = arr;
}
public T this[int index1, int index2]
{
get {return _arr[index1, index2];}
}
}
Then:
static void Main(string[] args)
{
string[,] string_variable = new string[1, 1];
string_variable[0, 0] = "unchanged";
Console.Write("Before calling the method string variable is {0}.\n", string_variable[0,0]);
Function(new ReadOnlyTwoDimensionalArray<string>(string_variable));
Console.Write("Can't touch this: {0}.\n", string_variable[0, 0]);
Console.ReadKey();
}
private static void Function(ReadOnlyTwoDimensionalArray<string> method_var)
{
// the compiler will complain if you try to do this:
//method_var[0, 0] ="changed";
// but this works just fine
Console.Write("Inside the method string variable is {0}.\n", method_var[0, 0]);
}
Alternatively, you could make sure that you only give Function a copy of the original array. But that obviously has some performance implications.
Response to Edits
The example you give to show how string variables work isn't really equivalent to the original. In that second example, you are changing the value of the variable locally, but that value is just a memory address--you're not actually changing the string itself. You could do the same thing with an array like this:
private static void Function(string [,] method_var)
{
method_var = new string[1, 1] {{"changed"}};
Console.Write("Inside the method string variable is {0}.\n", method_var[0, 0]);
}
By doing this, you are changing the value of the method_var variable, not the values in the array that it is pointing to.
Eric Lippert's comments below this post explain very clearly how C/C++ can give you read-only behavior on an array, but won't allow you to change the array's values locally without also changing them in the array that the calling method is referencing. He rightly points out that this is not a limitation of C#: it is a fundamental principle of how memory allocation works. Values passed from one method to another can either be passed by copying all their contents or by just copying a reference to their contents. For small values, you can have a value type, and C# will pass their entire value. For larger values like arrays, it would be expensive and error-prone to copy their entire value, so the language will not attempt to do this automatically--you must do it explicitly.
I'd just simply use Copy() to get a new instance with the same content:
string[,] newArray = new string[1, 1];
Array.Copy(string_variable , 0, newArray, 0, string_variable.Lenght);
Function(newArray);

Lambdas in C# Capturing Outer Variables - Pls explain example from book "C# in nutshell 5.0"

What difference between
static Func<int> Natural()
{
int seed = 0;
return () => seed++; // Returns a closure
}
and
static Func<int> Natural()
{
return() => { int seed = 0; return seed++; };
}
Why
static void Main()
{
Func<int> natural = Natural();
Console.WriteLine (natural());
Console.WriteLine (natural());
}
shows 0 1 for first Natural() and 0 0 for second one? Thanks!
The difference is that in the first version, you're declaring a variable and then capturing the variable in the lambda expression. The variable itself "survives" across multiple invocations of the delegate.
In the second example, you're declaring a variable inside the lambda expression, so every time the delegate is executed, the variable effectively starts again.
To put it another way, it's the difference between:
class NaturalImpl
{
public int seed;
public int Method()
{
return seed++;
}
}
Func<int> natural = new NaturalImpl().Method;
and:
class NaturalImpl
{
public int Method()
{
int seed = 0;
return seed++;
}
}
Func<int> natural = new NaturalImpl().Method;
Note the difference between the instance variable in the first version, and the local variable in the second.
(That's not exactly what the implementation of the second form would look like; it would be a static method in the enclosing class as it's stateless, but...)
In the first case, whenever Natural is called it returns a function that refers to the same seed variable each time (the one that's defined inside Natural itself).
In the second case it returns a function that refers to a different seed variable each time (the one that's defined inside the body of said function).
It stands to reason that in the first case each returned function will be able to "see" changes to seed made by the others because all of them are working on the same value.

Run multiply instances of the same method simultaneously in c# without data loss?

I really don't understand Tasks and Threads well.
I have a method inside three levels of nested for that I want to run multiple times in different threads/tasks, but the variables I pass to the method go crazy, let me explain with some code:
List<int> numbers=new List<int>();
for(int a=0;a<=70;a++)
{
for(int b=0;b<=6;b++)
{
for(int c=0;b<=10;c++)
{
Task.Factory.StartNew(()=>MyMethod(numbers,a,b,c));
}
}
}
private static bool MyMethod(List<int> nums,int a,int b,int c)
{
//Really a lot of stuff here
}
This is the nest, myMethod really does a lot of things, like calculating the factorial of some numbers, writing into different documents and matching responses with a list of combinations and calling other little methods, it has also some return value (booleans), but I don't care about them at the moment.
The problem is that no task reach an end, it's like everytime the nest call the method it refreshes itself, removing previous instances.
It also give an error, "try to divide for 0", with values OVER the ones delimited by FORs, for example a=71, b=7, c=11 and all variables empty(that's why divided by zero). I really don't know how to solve it.
The problem is, that you are using a variable that has been or will be modifed outside your closure/lambda. You should get a warning, saying "Access to modified closure".
You can fix it by putting your loop variables into locals first and use those:
namespace ConsoleApplication9
{
using System.Collections.Generic;
using System.Threading.Tasks;
class Program
{
static void Main()
{
var numbers = new List<int>();
for(int a=0;a<=70;a++)
{
for(int b=0;b<=6;b++)
{
for(int c=0;c<=10;c++)
{
var unmodifiedA = a;
var unmodifiedB = b;
var unmodifiedC = c;
Task.Factory.StartNew(() => MyMethod(numbers, unmodifiedA, unmodifiedB, unmodifiedC));
}
}
}
}
private static void MyMethod(List<int> nums, int a, int b, int c)
{
//Really a lot of stuffs here
}
}
}
Check your for statements. b and c are never incremented.
You then have a closure over the loop variables which is likely to be the cause of other problems.
Captured variable in a loop in C#
Why is it bad to use an iteration variable in a lambda expression

Closures and java anonymous inner classes

Would anyone be so kind to post the equivalent Java code for a closure like this one (obtained using C#) with anonymous inner classes?
public static Func<int, int> IncrementByN()
{
int n = 0; // n is local to the method
Func<int, int> increment = delegate(int x)
{
n++;
return x + n;
};
return increment;
}
static void Main(string[] args)
{
var v = IncrementByN();
Console.WriteLine(v(5)); // output 6
Console.WriteLine(v(6)); // output 8
}
Furthermore, can anyone explain how partial applications can be obtained if lexical closures are available and viceversa? For this second question, C# would be appreciated but it's your choice.
Thanks so much.
There is no closure yet in Java. Lambda expressions are coming in java 8. However, the only issue with what you're trying to translate is that it has state, which not something that lamba expressions will support i don't think. Keep in mind, it's really just a shorthand so that you can easily implement single method interfaces. You can however still simulate this I believe:
final AtomicInteger n = new AtomicInteger(0);
IncrementByN v = (int x) -> x + n.incrementAndGet();
System.out.println(v.increment(5));
System.out.println(v.increment(6));
I have not tested this code though, it's just meant as an example of what might possibly work in java 8.
Think of the collections api. Let's say they have this interface:
public interface CollectionMapper<S,T> {
public T map(S source);
}
And a method on java.util.Collection:
public interface Collection<K> {
public <T> Collection<T> map(CollectionMapper<K,T> mapper);
}
Now, let's see that without closures:
Collection<Long> mapped = coll.map(new CollectionMapper<Foo,Long>() {
public Long map(Foo foo) {
return foo.getLong();
}
}
Why not just write this:
Collection<Long> mapped = ...;
for (Foo foo : coll) {
mapped.add(foo.getLong());
}
Much more concise right?
Now introduce lambdas:
Collection<Long> mapped = coll.map( (Foo foo) -> foo.getLong() );
See how much nicer the syntax is? And you can chain it too (we'll assume there's an interface to do filtering which which returns boolean values to determine whether to filter out a value or not):
Collection<Long> mappedAndFiltered =
coll.map( (Foo foo) -> foo.getLong() )
.filter( (Long val) -> val.longValue() < 1000L );
This code is equivalent I believe (at least it produces the desired output):
public class Test {
static interface IncrementByN {
int increment(int x);
}
public static void main(String[] args) throws InterruptedException {
IncrementByN v = new IncrementByN() { //anonymous class
int n = 0;
#Override
public int increment(int x) {
n++;
return x + n;
}
};
System.out.println(v.increment(5)); // output 6
System.out.println(v.increment(6)); // output 8
}
}
Assuming we have a generic function interface:
public interface Func<A, B> {
B call A();
}
Then we can write it like this:
public class IncrementByN {
public static Func<Integer, Integer> IncrementByN()
{
final int n_outer = 0; // n is local to the method
Func<Integer, Integer> increment = new Func<Integer, Integer>() {
int n = n_outer; // capture it into a non-final instance variable
// we can really just write int n = 0; here
public Integer call(Integer x) {
n++;
return x + n;
}
};
return increment;
}
public static void main(String[] args) {
Func<Integer, Integer> v = IncrementByN();
System.out.println(v.call(5)); // output 6
System.out.println(v.call(6)); // output 8
}
}
Some notes:
In your program, you capture the variable n by reference from the enclosing scope, and can modify that variable from the closure. In Java, you can only capture final variables (thus capture is only by value).
What I did here is capture the final variable from the outside, and then assign it into a non-final instance variable inside the anonymous class. This allows "passing info" into the closure and at the same time having it be assignable inside the closure. However, this information flow only works "one way" -- changes to n inside the closure is not reflected in the enclosing scope. This is appropriate for this example because that local variable in the method is not used again after being captured by the closure.
If, instead, you want to be able to pass information "both ways", i.e. have the closure also be able to change things in the enclosing scope, and vice versa, you will need to instead capture a mutable data structure, like an array, and then make changes to elements inside that. That is uglier, and is rarer to need to do.

List Collection object as Method Parameter

Can anyone explain how the memory allocation is done while invoking a method having list collection as parameter. Since the code snippet below though apparently seems to result same but it is not resulting same.
So I would like to know the difference in both the method call in terms of memory allocation.
using System;
using System.Collections.Generic;
namespace ListSample
{
class ListSampleClass
{
static void Main(string[] args)
{
List<int> i = new List<int>();
i.Add(10);
i.Add(15);
SampleMethod1(i);
Console.WriteLine("Result of SampleMethod1:"+i[0]);
SampleMethod2(i);
Console.WriteLine("Result of SampleMethod2:" + i[0]);
Console.ReadKey();
}
public static void SampleMethod1(List<int> i)
{
List<int> j = new List<int>();
j.Insert(0,20);
i = j;
}
public static void SampleMethod2(List<int> i)
{
List<int> j = new List<int>();
j = i;
j.Insert(0, 20);
}
}
}
Unless you specify ref or out, parameters are passed by value. For reference types, that means a reference to the object (the List<int> in this case) is passed by value.
"Pass by value" means that the argument (the expression in the calling statement) is evaluated, and then the resulting value is copied into the parameter (the variable listed in the method signature). Any further changes to the parameter, in terms of assigning it a new value, are not seen by the caller. (But keep reading...)
That means that in your first method call:
public static void SampleMethod1(List<int> i)
{
List<int> j = new List<int>();
j.Insert(0,20);
i = j;
}
you're creating a new list, inserting a value into it, and then copying the reference to that new list to i - but that has no effect at all. The parameter is effectively just another local variable - a change to the value of the variable itself doesn't affect the caller.
Now compare that with your second method:
public static void SampleMethod2(List<int> i)
{
List<int> j = new List<int>();
j = i;
j.Insert(0, 20);
}
This creates a new list and then immediately ignores it, instead assigning the reference to the list passed in (as i) to j. It then inserts a value into the list. The net result of this method is that a value is inserted into the list. It's equivalent to:
public static void SampleMethod2(List<int> i)
{
i.Insert(0, 20);
}
Note that this is not changing the value of the parameter. It's making a change to the object that the value of the parameter refers to. This is a crucial difference to understand.
I have an article on parameter passing and another one on reference and value types which may help you understand this more.

Categories