This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
If I write a = a +115 my MessageBox will return 215 but if write like a=115; it will display 115.
Why is that?
private void button1_Click(object sender, EventArgs e)
{
int c=100;
MessageBox.Show(Count(c).ToString());
}
public int Count(int a)
{
a=115;
return a;
}
The question is very hard to decipher. I think that you have tried two different versions of the function that you named Count, as shown below.
Consider this version of the function:
public int Count1(int a)
{
a = 115;
return a;
}
It returns 115 no matter what value you pass as the parameter. You are overwriting the parameter with the assignment a = 115. The parameter is therefore utterly pointless.
And now the other version:
public int Count2(int a)
{
a = a + 115;
return a;
}
This version of the function receives a parameter in the variable a. It then adds on 115 to that value, and returns the result. So when you call it like this:
Count2(100)
the value that is returned is 215.
It might be easier to understand if you wrote the functions like this:
public int Count1(int a)
{
return 115; //very clearly the input parameter is ignored
}
public int Count2(int a)
{
return a + 115; //but in this version, the input parameter is used
}
These versions are exactly equivalent to your versions but I hope you'll find them easier to understand.
Here are three versions of your code to demonstrate what is going on, and what I think you're really asking:
Original:
private void button1_Click(object sender, EventArgs e)
{
// Set c to 100
int c=100;
// Print the result of Count, which (see below) is ALWAYS 115.
MessageBox.Show(Count(c).ToString());
}
public int Count(int a)
{
// Set a to 115 (there is no add here, I think this is a typo)
a=115;
// Return a, which is ALWAYS 115.
return a;
}
What I think you meant:
private void button1_Click(object sender, EventArgs e)
{
// Set c to 100
int c=100;
// Print the result of Count, which will be 215.
MessageBox.Show(Count(c).ToString());
}
public int Count(int a)
{
// Add 115 to a.
a+=115;
// Return the result (if a == 100, this will return 215)
return a;
}
What I think you're getting at:
private void button1_Click(object sender, EventArgs e)
{
// Set c to 100
int c=100;
// Call the count function, passing in a reference for c.
Count(ref c);
// Print the value of c. This will be 215 because the Count function set c to a new value.
MessageBox.Show(c.ToString());
}
public void Count(ref int a)
{
a+=115;
}
In this last case, I changed the function to public void Count(ref int a). The ref modifier allows the function to assign a new value using a reference to another variable. Normally, parameters are "by value", where a copy of the variable's value is passed in.
Note that the second version would be preferred in this case. By reference parameters should only be used when they are truly necessary, not as a replacement for a simple return value.
a = 115 sets an integer variable to 115, a += 115 or a = a + 115 will add 115 to the value for a and then you are returning the result of that value
if you pass 100 to function which has statement a = a + 115 which is a = 100 + 115 then it should return 215
public int Count(int a)
{
a = a + 115; // a = 100 + 115
return a;
}
When you do a=115, it displays 115 because you're ASSIGNING 115 to a. When you use the =, you're ASSIGNING the right value to the left value. Much the same you're doing when you do int c=100. You're assigning c to be 100.
When you pass in c, c is 100, and your formula is a=a+115, then a will be 215. When you pass in a value like you're doing, a will be 100. So, when you do your formula of a=a+115, you're saying a=100+115, and you'll get the 215.
Is the confusion because you think "a" and "c" are separate values?
The method Count(int a) doesn't care that the name of the value was
originally "c". Once it is inside of that method, it will be referred
to only as "a."
public int Count(int a)
{
a = a+115;
return a;
}
So step-by-step:
1) You pass the value 100 to the Count() method. (a = 100)
2) Count() sets the value of a to 100 + 115. (a = 215)
3) 215 is returned back to your calling method.
4) Your calling method displays 215 as a string.
Does that help?
Your Count() method just throws away the value it was passed and returns 115. If you replace a=115 with a=a+115, and pass it 100, it will return 215. This is all as expected.
a=a+115 means "take the value of a, add 115 to it, and assign the total to a."
This is all working as expected.
It looks like you're wondering how the variable a translates to your message box. This is because the variable a is in your count() function. Changing its value changes the result of the count function. And since your message box gets its value from count, there you have it.
Related
I've found a really cool feature of a compilator. However, I cannot understand logic of this behaviour.
static int IncrementValue(ref int i) { return i++;}
and Main method:
static void Main(string[] args)
{
int a = 2;
int b = IncrementValue(ref a);
Console.WriteLine(a+b);
}
The output is 5.
My question is:
Why is "b" field equal 2? (In my view, it ought to be 3 as "ref" keyword is not copying by value, but the keyword takes field by value. Consequently, "b" should be as "a+1")
Since you wrote it as;
return i++
This will still return 2 as a value but it will increase a value to 3 after the expression.
If you wrote it as;
return ++i
This will return incremented value which is 3, and since a will be 3 after the execute it, it will be printed 6 as a result.
Further reading
What is the difference between ++i and i++?
i++ is the post increment operator. It will increment the value afterwards, instead of before the value is returned.
Change i++ to ++i to make it increment before the value is returned, or increment the value in a separate statement and then return the value:
static int IncrementValue(ref int i) { return ++i; }
Or:
static int IncrementValue(ref int i) { i++; return i; }
(The reason you see different values when returning the integer, is that the result is copied. It is not a reference, else the return statement would not be useful at all).
I have a 'Movie' class in my C# code that has an int[] ratings = new int[10]; as a field. I would like to place numbers in this empty array from my main program.
For that, I would need a method, that could point to the actual free index of the array to put the integer there, but the other integer that would point to the free index would be reset to 0 everytime the method is called. Thus, my question is, that how can I place an integer in my method that is increased everytime the method was called.
This is the method in the class:
public void Rate(int rating)
{
int x = 0;
ratings[x] = rating;
}
This is how I call it in the main program
Movie asd = new Movie(blabla...);
Rate.asd(1);
Rate.asd(1);
Rate.asd(1);
So I called it 3 times, and I would want the 'x' integer in the class's method to increase.
Thanks in advance.
First of all, you have an error in the code you have posted.
As I suppose rather than:
Movie asd = new Movie(blabla...);
Rate.asd(1);
Rate.asd(1);
Rate.asd(1);
you want to paste here:
Movie asd = new Movie(blabla...);
asd.Rate(1);
asd.Rate(1);
asd.Rate(1);
As C# does not allow to use static method variables (like i.e. C++ does) you have two options:
first, make x value (from Rate method) a Movie's class variable, so Rate method will "remember" the next index,
second (and better) rather than intiger array - if possible use any kind of list or queue (which can manage indexing for you).
The problem is that local variables are discarded when exiting a method.
class SomeClass
{
private int x = 42;
public void DoSometing(int y)
{
int a = y + 5;
x += a * a;
// a stops to exist here
}
}
Solution is to store the variable in the containing class as well
class SomeOtherClass
{
private int x = 42;
private int a = 0;
public void DoSomething(int y)
{
a = y + 5;
x += a * a;
}
}
Now SomeOtherClass remembers the value of a. That's basically the point of member variables a.k.a. fields - to store the state of the object.
More appropriate for your problem:
class ClassWithAnArrayAndCount
{
private int[] values = new int[10];
private int taken = 0;
public void Add(int value)
{
if (taken == 10)
throw new ArgumentOutOfRangeException(); // sorry, no more space
values[taken++] = value;
}
public int Taken { get { return taken; } }
}
http://simpleprogrammer.com/2010/09/24/explaining-what-action-and-func-are/
The above code explains in simple terms about Action and Func.
Still I am not getting what it is for 100%. Or not able to make the code work for me.
public void SteamVegetable(Vegetable vegetable, int timeInMinutes)
{
CookVegetable(vegetable, Steam, timeInMinutes);
}
public void FryVegetable(Vegetable vegetable, int timeInMinutes)
{
CookVegetable(vegetable, Fry, timeInMinutes);
}
public void BakeVegetable(Vegetable vegetable, int timeInMinutes)
{
CookVegetable(vegetable, Bake, timeInMinutes);
}
public void CookVegetable(Vegetable vegetable,
Action<Vegetable, CookingTime> cookingAction,
int timeInMinutes)
{
Clean(vegetable);
cookingAction(vegetable, Minutes.Is(timeInMinutes));
Serve(vegetable);
}
Can someone help me to convert the code from vegetable to numbers and Steam --> Addition, Fry --> Multiplication, Bake --> subtraction when two operands are passed to it.
When I see the code working I can understand it better.
In the example you provided, Fry, Steam, and Bake are probably supposed to be methods.
Basically, Actions and Funcs let you pass a chunk of code into a method, then execute that chunk of code.
So, you could do
public void Foo(Action<int> actionToPerform, int someInt)
{
actionToPerform(someInt);
}
Then, you could use the Foo method with any "chunk of code" that takes an integer.
So,
public void Bar()
{
Action<int> writeToConsole = i => { Console.WriteLine(i); }
Action<int> writeToSomeLogger = i => { Logger.WriteLog(i); }
Foo(writeToConsole, 10);
Foo(writeToSomeLogger, 100);
}
I'm going to throw my example in.. I tried to make it simple, so hopefully this helps.
Take this for example:
class MathClass {
public int Add(int number1, int number2) {
return DoSomeMathOperation(number1, number2, theAddingIsActuallyDoneHere); // The method "theAddingIsActuallyDoneHere" below is what gets called.
}
private int theAddingIsActuallyDoneHere(int number1, int number2) {
return number1 + number2;
}
public int Multiply(int number1, int number2) {
return DoSomeMathOperation(number1, number2, theMultiplicationIsDoneHere); // The method "theMultiplicationIsDoneHere" is what gets called.
}
private int theMultiplicationIsDoneHere(int number1, int number2) {
return number1 * number2;
}
public int DoSomeMathOperation(int number1, int number2, Func<int, int, int> mathOperationFunc) {
return mathOperationFunc(number1, number2); // This is where you call the method passed in above.
}
}
The above code, can be used like this:
MathClass mathClass = new MathClass();
Console.WriteLine(mathClass.Add(5, 10)); // displays 15
Console.WriteLine(mathClass.Multiply(5, 5)); // displays 25
Imagine though, that you required a subtraction method. You can create one, via the DoSomeMathOperation function, which expects a Func<int, int, int>, which is a function that "takes 2 integer parameters and returns an integer". This would be implemented as follows:
Console.WriteLine(mathClass.DoSomeMathOperation(100, 50, (num1, num2) => num1 - num2)); // displays "50"
In the above code, you're passing the numbers 100 and 50 into the DoSomeMathOperation method, and those two parameters are being passed into the Func<int, int, int>. The result is then returned.
..hopefully that makes sense..
I might be wrong in understanding what you want, but I'll try to answer it. Note, that I omit many complex things in example, like I would use generics instead of plain int values, but this will just create redundant complexity in the example.
In example below I just define high-order function, which takes two int values, function, that transforms two values into string (i.e. encapsulate some behavior) and them embrace this result into enclosing and opening tags, one of which is passed in. Note, that I assume you are familiar with lambda notation in C#.
ApplyAndPrettyPrint(100, 3, "summ of 100 and 3 is equal to: ", (x,y) => (x*y).ToString("N0"));
ApplyAndPrettyPrint(100, 3, "100 to power 3 is: ", (x,y) => (Math.Pow(x,y)).ToString("N0"));
ApplyAndPrettyPrint(2, 33, "2 * root of 33 is: ", (x,y) => (x * Math.Sqrt(y)).ToString("N0"));
public void ApplyAndPrettyPrint( int firstNumber, int secondNumber, string startTag, Func<int, int, string> evaludationFunction)
{
string result = startTag;
result += evaludationFunction(firstNumber, secondNumber);
result += ";";
Console.WriteLine (result);
}
So that Func here is used like a box, with two integers as input and one string as output.
Second example shows how we can pass Action into method, that will be evaluated over some array of numbers. Again, I omit details of IEnumerable interfaces and generics.
int[] numbers = new []{ 1, 2, 4, 5, 6, 7 };
ApplyForEach(numbers, (x) => Console.WriteLine ("square of {0} is {1}", x, x*x));
public void ApplyForEach(int[] numbers, Action<int> someFunction)
{
foreach (var number in numbers)
{
someFunction(number);
}
}
The result will just print squares of integers with some descriptive chars. In other word Action is delegate with no outputs. You can think of them as box with some inputs, but with no outputs at all.
Hope that this will do the trick for your understanding. The bottom line is that the only difference between delegate types of Action and Func is the semantics of the last generic type: in Func it is the returning value, in Action returning value is void, so last generic type just goes to input parameter.
If you find this topic somewhat difficult, Jon Skeet describes delegates within Chapter 5 "Fast-tracked delegates" in his marvelous book "C# in Depth"
I created a method that takes 2 out parameters. I noticed that it is possible for calling code to pass in the same variable for both parameters, but this method requires that these parameters be separate. I came up with what I think is the best way to validate that this is true, but I am unsure if it will work 100% of the time. Here is the code I came up with, with questions embedded.
private static void callTwoOuts()
{
int same = 0;
twoOuts(out same, out same);
Console.WriteLine(same); // "2"
}
private static void twoOuts(out int one, out int two)
{
unsafe
{
// Is the following line guaranteed atomic so that it will always work?
// Or could the GC move 'same' to a different address between statements?
fixed (int* oneAddr = &one, twoAddr = &two)
{
if (oneAddr == twoAddr)
{
throw new ArgumentException("one and two must be seperate variables!");
}
}
// Does this help?
GC.KeepAlive(one);
GC.KeepAlive(two);
}
one = 1;
two = 2;
// Assume more complicated code the requires one/two be seperate
}
I know that an easier way to solve this problem would simply be to use method-local variables and only copy to the out parameters at the end, but I am curious if there is an easy way to validate the addresses such that this is not required.
I'm not sure why you ever would want to know it, but here's a possible hack:
private static void AreSameParameter(out int one, out int two)
{
one = 1;
two = 1;
one = 2;
if (two == 2)
Console.WriteLine("Same");
else
Console.WriteLine("Different");
}
static void Main(string[] args)
{
int a;
int b;
AreSameParameter(out a, out a); // Same
AreSameParameter(out a, out b); // Different
Console.ReadLine();
}
Initially I have to set both variables to any value. Then setting one variable to a different value: if the other variable was also changed, then they both point to the same variable.
I am having trouble getting a method working and I am not sure I am doing it the correct way. What I want to do is to send a string from a form by a button_click into a class and process it there for errors(tryparse method) and the send a boolvalue back to then either report and error to the user or to print input in an listbox.
This is the form code I have that is supposed to send the string into the class.
private void btnOK_Click(object sender, EventArgs e)
{
Errorcheck.GetDouble(numChoice);
}
and then the Errorcheck class:
public static bool GetDouble(string numChoice, out double value, double minLimit, double maxLimit)
{
while (!double.TryParse(numChoice, out value))
{
if ((value >= minLimit) && (value <= maxLimit))
{
return true;
}
}
return false;
}
How do I retrieve the bool value from the Errorcheck class? if it was ok or not. Am I doing the right way or is there a quicker way to go about it?
private void btnOK_Click(object sender, EventArgs e)
{
double foo;
var myresult = Errorcheck.GetDouble(numChoice, out foo, 1, 2);
//When myresult == true, foo contains the parsed value
}
myresult will contain the result returned by GetDouble either true (value could be parsed and is within limits) or false (value could be parsed but was out of limits or failed to parse in the first place). Also, foo will contain 0 if parsing failed, otherwise the parsed value (which, may or may not!) be within the limits.
I do, however, have some problems with your code. First; why is your class named Errorcheck while, in fact, it doesn't do error-checking (what is that anyway?) but parse a value.
Second, why use the while() construct?
public static bool GetDouble(string numChoice, out double value, double minLimit, double maxLimit)
{
return double.TryParse(numChoice, out value)
&& ((value >= minLimit) && (value <= maxLimit));
}
Third; GetDouble() doesn't actually "get" a "double". It checks if a value is parseable as a double and, if so, is within bounds. It returns a bool for Pete's sake.
EDIT Scratch that; I missed the out on the method signature. It returns a bool and also the value.
...and then some more but I might be nitpicking :P
And, last but not least, I don't see what this has to do with "how bool values and variables get sent between classes/forms"?
Take my, well intended, advice and get a good C# or general book on programming and brush up your basic skills a little. You will only benefit and soon you'll see why your code is, no flame intended, "bad" in many ways.
I would do it like that:
private void btnOK_Click(object sender, EventArgs e)
{
double parsedValue;
if (Errorcheck.IsDoubleBetween(numChoice, out parsedValue, maxValue, minValue))
{
//Your code here
}
}
Errorcheck code:
public static bool IsDoubleBetween(string numChoice, out double value, double minLimit, double maxLimit)
{
bool result = double.TryParse(numChoice, out value) && (value >= minLimit) && (value <= maxLimit);
return result;
}
As you can see, there are a few changes:
The name IsDoubleBetween explains the method logic.
There is a call to IsDoubleBetween with the right parameters.
There is a use of IsDoubleBetween return value.
IsDoubleBetween code is more readable.
In this case i would try to separate the two operations of IsDoubleBetween to two methods so there will be single responsibility to each - parsing and checking between value